Мещерский. Задача 8.21
Визуализация 3D-задачи по статике на JavaScript
Исполнитель: Белоусова Екатерина
Группа 23604/1 Кафедра Теоретической механики
Формулировка задачи[править]
Решение задачи[править]
<syntaxhighlight lang="javascript" line start="1" enclose="div">
<!DOCTYPE html>
<head> <script src = "http://tm.spbstu.ru/htmlets/Belousova/Statika/three.js"> </script> <script src ="http://tm.spbstu.ru/htmlets/Belousova/Statika/stats.min.js"> </script> <script src ="http://tm.spbstu.ru/htmlets/Belousova/Statika/OrbitControls.js"> </script> <script src ="http://tm.spbstu.ru/htmlets/Belousova/Statika/dat.gui.js"> </script> <style> body { margin:0; overflow:hidden; } </style> <body>
<script>
var renderer, scene, camera, stats, axes, cubeGeometry1, cubeMaterial1, cube1, cubeGeometry2, cubeMaterial2, cube2, cubeGeometry3, cubeMaterial3, cube3; var cubeGeometry4, cubeMaterial4, cube4, cubeGeometry5, cubeMaterial5, cube5, spotLight, Width1=5, Length1=3, Height1=0, Length2=1; var Length3, Width3=0.05, Height3=0.05, betta, control, controls, controls1, veccZa, veccXa, veccZb,veccXb, veccP, veccS, norm=10, vectXa, P1=120, vectXb; var vectS, vectZb, vectZa, alpha=Math.PI/6, gamma, psi=Math.PI/6, ygol, ambiColor="#0c0c0c", ambientLight;
///// ЗАДАНИЕ ПАРАМЕТРОВ, УКАЗАННЫХ В ЗАДАЧЕ ///// var psi1=Math.PI/3; var weight=120;
function init() { scene = new THREE.Scene(); // создаем сцену camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000); // создаем камеру
renderer = new THREE.WebGLRenderer(); renderer.setClearColor(0XEEEEEE,1); renderer.setSize(window.innerWidth,window.innerHeight); renderer.shadowMap.enabled=true;
axes = new THREE.AxisHelper(20); // создаем координатные оси scene.add(axes);
control = new THREE.OrbitControls(camera,renderer.domElement);
controls = new function() // создаем переключатели, позволяющие изменять входные параметры { this.weight = 120; // вес первого тела this.alpha = Math.PI/6; // угол между крышкой и ящиком this.displayForces = true; // модуль отображения задачи }
controls1=new function() { this.Xa='0'; // вывод полученных в ходе решения задачи значений this.Xb='0'; this.Zb='0'; this.Za='0'; this.S='0'; this.gamma='0'; }
var gui = new dat.GUI(); // позволяем менять каждый из параметров в определенном диапазоне, в случае изменения вызываем функцию, перестраивающую выводимую на экран картинку gui.add(controls, 'weight',0,150).onChange(ReDraw); gui.add(controls, 'alpha',0,Math.PI/2).onChange(ReDraw); gui.add(controls, 'displayForces').onChange(Change); // параметр, определяющий вариант отображения задачи (с отображением сил и без отображения) gui.add(controls1, 'gamma').listen(); gui.add(controls1, 'Xa').listen(); gui.add(controls1, 'Xb').listen(); gui.add(controls1, 'Za').listen(); gui.add(controls1, 'Zb').listen(); gui.add(controls1, 'S').listen();
ambientLight=new THREE.AmbientLight(ambiColor); scene.add(ambientLight); document.getElementById("WebGL").appendChild(renderer.domElement); camera.position.x = 0; // задаем местоположение камеры camera.position.y = 0; camera.position.z = 20; camera.lookAt(0,0,0); spotLight=new THREE.SpotLight(0xffffff); spotLight.position.set(90,-45,-90); scene.add(spotLight); stats = initStats(); Draw(); renderScene();
window.addEventListener('resize',onResize,false); };
function Change() // функция, меняющая вариант отображения задачи { if (controls.displayForces == true) // если требуется отображение сил {VisionTrue();} if (controls.displayForces == false) // если не требуется отображение сил {VisionFalse();} }
function VisionTrue() // функция, рисующая задачу с отображением сил { ReDraw(); }
function VisionFalse() // общая картинка задача без отображения сил { ReDraw(); veccZa.visible = false; // убираем векторы, отображающие силы veccXa.visible = false; veccZb.visible = false; veccXb.visible = false; veccP.visible = false; veccS.visible = false; renderScene(); }
function ReDraw() // функция, перерисовывающая всю картинку { scene.remove(cube1); // удаляем ранее созданные объекты scene.remove(cube2); scene.remove(cube3); scene.remove(cube4); scene.remove(cube5); scene.remove(cube6); scene.remove(cube7); P1 = controls.weight; // меняем значения параметров на те, что ввел пользователь psi = controls.alpha; Draw(); }
function Draw() {
psi1 = Math.PI/2-psi; controls1.gamma= psi1*180/Math.PI; // вывод решения на экран
vectXa = P1/2*(Math.cos(psi1)*Math.cos(psi1)/Math.sin(psi1)); controls1.Xa= vectXa;
vectXb = 0; controls1.Xb= vectXb;
vectS = P1*Math.cos(psi1)/(2*Math.sin(psi1)); controls1.S= vectS;
vectZa = P1/2*(1-Math.cos(psi1)); controls1.Za= vectZa;
vectZb = (P1/2); controls1.Zb= vectZb;
///// СОЗДАНИЕ ЯЩИКА С КРЫШКОЙ /////
cubeGeometry1 = new THREE.CubeGeometry(Width1,Length1,Height1); // задаем геометрию cubeMaterial1 = new THREE.MeshLambertMaterial({color:0xcccccc}); // задаем материал cube1 = new THREE.Mesh(cubeGeometry1,cubeMaterial1); // создаем тело с заданными геометрией и материалом cube1.rotation.x = -0.5*Math.PI; // задаем поворот тела в пространстве cube1.position.x =Width1/2; // смещаем его в нужное положение cube1.position.y = -Length2; cube1.position.z = Length1/2; scene.add(cube1); // добавляем тело в сцену
cubeGeometry2 = new THREE.CubeGeometry(Width1,Length2,Height1); cubeMaterial2 = new THREE.MeshLambertMaterial({color:0xcccccc}); cube2 = new THREE.Mesh(cubeGeometry2,cubeMaterial2); cube2.position.x = Width1/2; cube2.position.y = -Length2/2; cube2.position.z = Length1; scene.add(cube2);
cubeGeometry3 = new THREE.CubeGeometry(Width1,Length2,Height1); cubeMaterial3 = new THREE.MeshLambertMaterial({color:0xcccccc}); cube3 = new THREE.Mesh(cubeGeometry3,cubeMaterial3); cube3.position.x = Width1/2; cube3.position.y = -Length2/2; cube3.position.z = Height1; scene.add(cube3);
cubeGeometry4 = new THREE.CubeGeometry(Length1,Length2,Height1); cubeMaterial4 = new THREE.MeshLambertMaterial({color:0xcccccc}); cube4 = new THREE.Mesh(cubeGeometry4,cubeMaterial4); cube4.rotation.y = -0.5*Math.PI; cube4.position.x = Height1; cube4.position.y = -Length2/2; cube4.position.z = Length1/2; scene.add(cube4);
cubeGeometry5 = new THREE.CubeGeometry(Length1,Length2,Height1); cubeMaterial5 = new THREE.MeshLambertMaterial({color:0xcccccc}); cube5 = new THREE.Mesh(cubeGeometry5,cubeMaterial5); cube5.rotation.y = -0.5*Math.PI; cube5.position.x = Width1; cube5.position.y = -Length2/2; cube5.position.z = Length1/2; scene.add(cube5);
cubeGeometry6 = new THREE.CubeGeometry(Width1,Length1,Height1); cubeMaterial6 = new THREE.MeshLambertMaterial({color:0xcccccc}); cube6 = new THREE.Mesh(cubeGeometry6,cubeMaterial6); cube6.rotation.x = psi; cube6.position.x = Width1/2; cube6.position.y = Length1*Math.cos(psi)/2; cube6.position.z = Math.sin(psi)*Length1/2; scene.add(cube6);
Length3=Length1*Math.sqrt(2*(1-Math.sin(psi))); betta=(-Math.PI/2+psi)/2 cubeGeometry7 = new THREE.CubeGeometry(Width3,Length3,Height3); cubeMaterial7 = new THREE.MeshLambertMaterial({color:0xcccccc}); cube7 = new THREE.Mesh(cubeGeometry7,cubeMaterial7); cube7.rotation.x = betta; cube7.position.x = Width3/2; cube7.position.y = Length1*Math.cos(psi)/2; cube7.position.z = Length1-(Length1-Math.sin(psi)*Length1)/2; scene.add(cube7);
///// СОЗДАНИЕ ВЕКТОРОВ, ОТОБРАЖАЮЩИХ СИЛЫ, ДЕЙСТВУЮЩИЕ НА ТЕЛА /////
var vecP = new THREE.Vector3( 1, 1, 0 ); // создаем геометрию вектора, отображающего вес тела var vecS = new THREE.Vector3( 1, 2, 0 ); // создаем геометрию вектора, отображающего усилие в палочке var vecZa = new THREE.Vector3(0,0, 0 ); // создаем геометрию вектора, отображающего реакцию в точке А по оси ОZ var vecZb = new THREE.Vector3( 1, 0, 0 ); // создаем геометрию вектора, отображающего реакцию в точке B по оси ОZ var vecXa = new THREE.Vector3( 0, 0, 0 ); // создаем геометрию вектора, отображающего реакцию в точке А по оси ОХ var vecXb = new THREE.Vector3( 1, 0, 0 ); // создаем геометрию вектора, отображающего реакцию в точке В по оси ОХ var origin = new THREE.Vector3( 0, 0, 0 ); //задаем точку начала var originvecP = new THREE.Vector3( 0, 0, 0 ); // задаем точку начала var originvecS = new THREE.Vector3( -2.5, 1.5 ,0 ); // задаем точку начала var originvecZa = new THREE.Vector3( -1.5, 0.5, 0 ); // задаем точку начала var originvecZb = new THREE.Vector3( 2.5, 0.5,0 ); // задаем точку начала var originvecXa = new THREE.Vector3( -2.5, 0.5, 0 ); // задаем точку начала var originvecXb = new THREE.Vector3( 0, 0, 0 ); // задаем точку начала var hex = 0xDC143C; // задаем цвета var hex1 = 0x8B0000; var hex2 = 0xFF4500; var hex3 = 0x191970; var hex4 = 0x123456; var hex5 = 0x00ffee;
var length1 = P1/norm; // задаем длину (численно равную исходному параметру в задаче) veccP = new THREE.ArrowHelper( vecP, originvecP, length1, hex ); // создаем срелочку veccP.rotation.x = Math.PI-psi; // поворачиваем ее, чтобы ее ориентация соответствовала cube6.add( veccP ); // прикрепляем вектор к телу
var length2 = (P1*Math.cos(psi1)/(2*Math.sin(psi1)))/norm; veccS = new THREE.ArrowHelper( vecS, originvecS, length2, hex ); veccS.rotation.x= (-0.5*Math.PI+betta)+2*Math.PI+Math.PI/2+Math.PI/4+Math.PI/4-2*betta; veccS.rotation.y = Math.PI; veccS.rotation.z=Math.PI; cube6.add( veccS );
var length3 = (P1/2*(1-Math.cos(psi1)))/norm; veccZa = new THREE.ArrowHelper( vecZa, originvecZa, length3, hex2 ); veccZa.rotation.x = Math.PI; veccZa.rotation.y = Math.PI; cube4.add( veccZa );
var length4 = (P1/2)/norm; veccZb = new THREE.ArrowHelper( vecZb, originvecZb, length4, hex3 ); veccZb.rotation.x = 0.5*Math.PI; veccZb.rotation.y = 0.5*Math.PI; cube3.add( veccZb );
var length5 = (P1/2*(Math.cos(psi1)*Math.cos(psi1)/Math.sin(psi1)))/norm; veccXa = new THREE.ArrowHelper( vecXa, originvecXa, length5, hex2 ); veccXa.rotation.x = 0.5*Math.PI; veccXa.rotation.y = 0.5*Math.PI; cube3.add( veccXa );
var length6 = 0; veccXb = new THREE.ArrowHelper( vecXb, origin, length6, hex5 ); veccXb.rotation.x = 0.5*Math.PI; veccXb.rotation.y = 0.5*Math.PI; cube3.add( veccXb );
renderer.render(scene,camera); }
function renderScene() { stats.update(); P1 = controls.weight; psi = controls.alpha; requestAnimationFrame(renderScene); renderer.render(scene,camera); };
function initStats() { var stats=new Stats(); stats.setMode(0); stats.domElement.style.position='0px'; stats.domElement.style.left='0px'; stats.domElement.style.top='0px'; document.getElementById("Stats-output").appendChild(stats.domElement); return stats; };
function onResize() { camera.aspect=window.innerWidth/window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth,window.innerHeight); }
window.onload = init; </script> </body>
</head>