Мещерский Задача 6.11

Материал из Department of Theoretical and Applied Mechanics
Версия от 22:57, 1 июня 2017; Loban9614 (обсуждение | вклад) (Решение задачи)

Перейти к: навигация, поиск

Курсовой проект по информатике

Исполнитель: Лобанов Илья

Группа: 23604/1


Задача

UB98cczQ-0.png


Решение задачи

<syntaxhighlight lang="javascript" line start="1" enclose="div">

<html>

   <head>
 <script src ="http://tm.spbstu.ru/htmlets/Lobanov_I_Y/JS_files/three.js"></script>
 <script src ="http://tm.spbstu.ru/htmlets/Lobanov_I_Y/JS_files/stats.min.js"></script>
 <script src ="http://tm.spbstu.ru/htmlets/Lobanov_I_Y/JS_files/OrbitControls.js"></script>
 <script src ="http://tm.spbstu.ru/htmlets/Lobanov_I_Y/JS_files/dat.gui.js"></script>
   </head>
   <body>
       <script>
           
           var scene,     //Сцена.
               camera,    //Камера.
               renderer;  //Рендер.
           
           var LENGTH_AB = 20;  //Длина стойки AB.
           var RADIUS_RACK = 1; //Радиус стойки.
           var statFPS;         //Объект, для вывода информации о текущем FPS.
           
           var panelControlOptions; //Объект, через которую изменяется угол альфа и вес груза, а так же возможность отображения усилий.
           var panelInfoEffort;     //Объект, через который выводим информацию об усилиях.
           var gui;                 //Панель с интерфейсом.
           
           //Стойка AB.
           var geometryRackAB,  //Геометрическая фигура.
               materialRackAB,  //Материал.
               meshRackAB,      //Объект сцены (на геом. фигуру накладываем материал).
               colorRackAB = {color: 0x6A5ACD}; //Цвет.
           
           //Стойка BD.
           var geometryRackBD,  //Геометрическая фигура.
               materialRackBD,  //Материал.
               meshRackBD,      //Объект сцены (на геом. фигуру накладываем материал). 
               colorRackBD = {color: 0x6A5ACD}; //Цвет.
           
           //Стойка BE.
           var geometryRackBE,  //Геометрическая фигура.
               materialRackBE,  //Материал.
               meshRackBE,      //Объект сцены (на геом. фигуру накладываем материал).
               colorRackBE = {color: 0x6A5ACD}; //Цвет.
           
           //Стойка AC.
           var geometryRackAC,  //Геометрическая фигура.
               materialRackAC,  //Материал.
               meshRackAC,      //Объект сцены (на геом. фигуру накладываем материал).
               colorRackAC = {color: 0x6A5ACD}; //Цвет.
           
           //Шарнир в точке B.
           var geometryHingeB,  //Геометрическая фигура.
               materialHingeB,  //Материал.
               meshHingeB,      //Объект сцены (на геом. фигуру накладываем материал).
               colorHingeB = {color: 0x6A5ACD}; //Цвет.
           
           //Шарнир в точке A.
           var geometryHingeA,  //Геометрическая фигура.
               materialHingeA,  //Материал.
               meshHingeA,      //Объект сцены (на геом. фигуру накладываем материал).
               colorHingeA = {color: 0x6A5ACD}; //Цвет.
           
           //Шарнир в точке D.
           var geometryHingeD,  //Геометрическая фигура.
               materialHingeD,  //Материал.
               meshHingeD,      //Объект сцены (на геом. фигуру накладываем материал).
               colorHingeD = {color: 0x6A5ACD}; //Цвет.
           
           //Шарнир в точке E.
           var geometryHingeE,  //Геометрическая фигура.
               materialHingeE,  //Материал.
               meshHingeE,      //Объект сцены (на геом. фигуру накладываем материал).
               colorHingeE = {color: 0x6A5ACD}; //Цвет.
           
           //Трос.
           var geometryCableBCP,  //Геометрическая фигура.
               materialCableBCP,  //Материал.
               meshCableBCP,      //Объект сцены (на геом. фигуру накладываем материал).
               colorCableBCP = {color: 0x000000}; //Цвет.
           
           
           //Наконечник стоки AC.
           var geometryEndRackAC, //Геометрическая фигура.
               materialEndRackAC, //Материал.
               meshEndRackAC,     //Объект сцены (на геом. фигуру накладываем материал).
               colorEndRackAC = {color: 0x6A5ACD}; //Цвет.
           
           //Груз.
           var geometryCargoP, //Геометрическая фигура.
               materialCargoP, //Материал.
               meshCargoP,     //Объект сцены (на геом. фигуру накладываем материал).
               colorCargoP = {color: 0xFF4500}; //Цвет.
           
           //Вектор усилия опоры AB.
           var vectorEffortAB,            //Вектор.
               colorEffortAB = 0xFF0000;  //Цвет.
           
           //Вектор усилия опоры BD.
           var vectorEffortBD,            //Вектор.
               colorEffortBD = 0xFF0000;  //Цвет.
           
           //Вектор усилия опоры BE.
           var vectorEffortBE,            //Вектор.
               colorEffortBE = 0xFF0000;  //Цвет.
           
           //Функции инициализации, которая создает необходимые объекты. Для работы приложения.
           function init() {
               scene = new THREE.Scene(); //Создаем сцену.
               camera = new THREE.PerspectiveCamera(100, window.innerWidth / window.innerHeight, 0.1, 100); //Добавляем камеру (точка с которой смотрит на сцену пользователь).
               renderer = new THREE.WebGLRenderer(); //Создаем WebGL-рендер.
               renderer.setSize(window.innerWidth, window.innerHeight); //Задаем размеры рендера.
               renderer.setClearColor(0xEEEEEE); //Задем цвет фона (серый цвет).
               //renderer.shadowMap.enabled=true;
               document.getElementById("WebGL").appendChild(renderer.domElement); //Добавляем рендер на страницу.
               
               //Задаем позицию камеры.
               camera.position.x = 0;
               camera.position.y = 0;
               camera.position.z = 40;
               camera.lookAt(0, 0, 0);
               
               axes = new THREE.AxisHelper(50); //Создаем оси координат.
               scene.add(axes); //Добавляем оси координат на сцену.
               control = new THREE.OrbitControls(camera,renderer.domElement); //Добавляем управление мышью (маштаб и ракурс обзора).
               
               //Создали объект через который меняем угол альфа и вес груза, а так же отображение усилий.
               panelControlOptions = new function() {
                   this.alpha = 0.0;    //Угол альфа.
                   this.weightP = 10.0; //Вес груза.
                   this.visibleEffort = true; //Отображения усилий.
               }
               
               //Создали объект, через который выводим информацию об усилиях.
               panelInfoEffort = new function() {
                   this.Sbd = '0';
                   this.Sbe = '0';
                   this.Sab = '0';
               }
               gui = new dat.GUI(); //Создали панель.
               //Добавили на панель возможность изменять угол. При изменения вызывается функция перерисовки сцены.
               gui.add(panelControlOptions, 'alpha', -90, 90).onChange(redrawCraneElements); 
               //Добавили на панель возможность изменять вес груза. При изменения вызывается функция перерисовки сцены.
               gui.add(panelControlOptions, 'weightP', 1, 100).onChange(redrawCraneElements); 
               //Добавили на панель возможность показа/скрытия усилий. При изменения вызывается функция перерисовки сцены.
               gui.add(panelControlOptions, 'visibleEffort').onChange(redrawCraneElements); 
               
               //Добавили на панель вывод усилий стоек.
               gui.add(panelInfoEffort, 'Sbd').listen();
               gui.add(panelInfoEffort, 'Sbe').listen();
               gui.add(panelInfoEffort, 'Sab').listen();
               
               drawStaticCraneElements();  //Добавление статичных элементов крана на сцену.
               drawDynamicCraneElements(); //Добавление динамических элементов крана на сцену.
   
               statFPS = initStatFPS();
               render(); //Отрисовываем сцену.
   
               //Повешали обработчик на событие: изменение размеров окна.
               window.addEventListener('resize',changeSizeWindow,false);
           }
           
           //Функция добавления статичный элементов крана на сцену.
           function drawStaticCraneElements() {
               //Создаем стойку AB.
               geometryRackAB = new THREE.CylinderGeometry(RADIUS_RACK, RADIUS_RACK, LENGTH_AB, 32); //Создаем фигуру (цилиндр).
               materialRackAB = new THREE.MeshBasicMaterial(colorRackAB);                            //Создаем материал.
               meshRackAB = new THREE.Mesh(geometryRackAB, materialRackAB);                          //Создаем объект сцены.
               //Задаем положение центра стойки.
               meshRackAB.position.x = 0;
               meshRackAB.position.y = LENGTH_AB / 2;
               meshRackAB.position.z = 0;
               //Помещаем стойку на сцену.
               scene.add(meshRackAB);
               
               //Создаем стойку BD.
               geometryRackBD = new THREE.CylinderGeometry(RADIUS_RACK, RADIUS_RACK, Math.sqrt(2) * LENGTH_AB, 32); //Создаем фигуру (цилиндр).
               materialRackBD = new THREE.MeshBasicMaterial(colorRackBD);                                           //Создаем материал.
               meshRackBD = new THREE.Mesh(geometryRackBD, materialRackBD);                                         //Создаем объект сцены.
               //Задаем положение центра стойки.
               meshRackBD.position.x = -Math.cos(Math.PI / 4) * (LENGTH_AB / 2);
               meshRackBD.position.y = LENGTH_AB / 2;
               meshRackBD.position.z = Math.sin(Math.PI / 4) * (LENGTH_AB / 2);
               //Задаем углы поворота стойки.
               meshRackBD.rotation.y = Math.PI / 4;
               meshRackBD.rotation.z = -Math.PI / 4;
               //Помещаем стойку на сцену.
               scene.add(meshRackBD);
               
               //Создаем стойку BE.
               geometryRackBE = new THREE.CylinderGeometry(RADIUS_RACK, RADIUS_RACK, Math.sqrt(2) * LENGTH_AB, 32); //Создаем фигуру (цилиндр).
               materialRackBE = new THREE.MeshBasicMaterial(colorRackBE);                                           //Создаем материал.
               meshRackBE = new THREE.Mesh(geometryRackBE, materialRackBE);                                         //Создаем объект сцены.
               //Задаем положение центра стойки.
               meshRackBE.position.x = -Math.cos(Math.PI / 4) * (LENGTH_AB / 2);
               meshRackBE.position.y = LENGTH_AB / 2;
               meshRackBE.position.z = -Math.sin(Math.PI / 4) * (LENGTH_AB / 2);
               //Задаем углы поворота стойки.
               meshRackBE.rotation.y = -Math.PI / 4;
               meshRackBE.rotation.z = -Math.PI / 4;
               //Помещаем стойку на сцену.
               scene.add(meshRackBE);
               
               //Создаем шарнир в точке B.
               geometryHingeB = new THREE.SphereGeometry(RADIUS_RACK, 32, 32);  //Создаем фигуру (сфера).
               materialHingeB = new THREE.MeshBasicMaterial(colorHingeB);       //Создаем материал.
               meshHingeB = new THREE.Mesh(geometryHingeB, materialHingeB);     //Создаем объект сцены.
               //Задаем положение центра шарнира.
               meshHingeB.position.y = LENGTH_AB;
               //Помещаем шарнир на сцену.
               scene.add(meshHingeB);
               
               //Создаем шарнир в точке A.
               geometryHingeA = new THREE.SphereGeometry(RADIUS_RACK, 32, 32);  //Создаем фигуру (сфера).
               materialHingeA = new THREE.MeshBasicMaterial(colorHingeA);       //Создаем материал.
               meshHingeA = new THREE.Mesh(geometryHingeA, materialHingeA);     //Создаем объект сцены.
               //Помещаем шарнир на сцену.
               scene.add(meshHingeA);
               
               //Создаем шарнир в точке D.
               geometryHingeD = new THREE.SphereGeometry(RADIUS_RACK, 32, 32);  //Создаем фигуру (сфера).
               materialHingeD = new THREE.MeshBasicMaterial(colorHingeD);       //Создаем материал.
               meshHingeD = new THREE.Mesh(geometryHingeD, materialHingeD);     //Создаем объект сцены.
               //Задаем положение центра шарнира.
               meshHingeD.position.x = -LENGTH_AB * Math.cos(Math.PI / 4);
               meshHingeD.position.z = LENGTH_AB * Math.sin(Math.PI / 4);
               //Помещаем шарнир на сцену.
               scene.add(meshHingeD);
               
               //Создаем шарнир в точке E.
               geometryHingeE = new THREE.SphereGeometry(RADIUS_RACK, 32, 32);  //Создаем фигуру (сфера).
               materialHingeE = new THREE.MeshBasicMaterial(colorHingeE);       //Создаем материал.
               meshHingeE = new THREE.Mesh(geometryHingeE, materialHingeE);     //Создаем объект сцены.
               //Задаем положение центра шарнира.
               meshHingeE.position.x = -LENGTH_AB * Math.cos(Math.PI / 4);
               meshHingeE.position.z = -LENGTH_AB * Math.sin(Math.PI / 4);
               //Помещаем шарнир на сцену.
               scene.add(meshHingeE);
               
               renderer.render(scene, camera); //Рендинг сцены.
           }
           //Функция добавления динамичных элементов крана на сцену.
           function drawDynamicCraneElements() {
               var ALPHA = panelControlOptions.alpha / 180 * Math.PI; //Получаем текущие значение угла альфа.
               var WEIGHT_P = panelControlOptions.weightP; //Получаем текущий вес груза.
               
               //Вычисляем усилия стоек.
               panelInfoEffort.Sbd = WEIGHT_P * (Math.cos(ALPHA) - Math.sin(ALPHA));
               panelInfoEffort.Sbe = WEIGHT_P * (Math.cos(ALPHA) + Math.sin(ALPHA));
               panelInfoEffort.Sab = -WEIGHT_P * Math.sqrt(2) * Math.cos(ALPHA);
               
               //Создаем стойку AC.
               geometryRackAC = new THREE.CylinderGeometry(RADIUS_RACK, RADIUS_RACK, Math.sqrt(2) * LENGTH_AB, 32); //Создаем фигуру (цилиндр).
               materialRackAC = new THREE.MeshBasicMaterial(colorRackAC);                                           //Создаем материал.
               meshRackAC = new THREE.Mesh(geometryRackAC, materialRackAC);                                         //Создаем объект сцены.
               //Задаем положение центра стойки.
               meshRackAC.position.x = Math.cos(ALPHA) * (LENGTH_AB / 2);
               meshRackAC.position.y = LENGTH_AB / 2;
               meshRackAC.position.z = -Math.sin(ALPHA) * (LENGTH_AB / 2);
               //Задаем углы поворота стойки.
               meshRackAC.rotation.y = ALPHA;
               meshRackAC.rotation.z = -Math.PI / 4;
               //Помещаем стойку на сцену.
               scene.add(meshRackAC);
               
               //Создаем тросс через точку B, C и P.
               geometryCableBCP = new THREE.Geometry(); //Создаем пустую геом. фигура.
               //Добавляем в фигуру 3 точки.
               geometryCableBCP.vertices.push(
                   new THREE.Vector3(0, LENGTH_AB + RADIUS_RACK, 0), //Точка B.
                   new THREE.Vector3(Math.cos(ALPHA) * (LENGTH_AB + RADIUS_RACK), LENGTH_AB + RADIUS_RACK, -Math.sin(ALPHA) * (LENGTH_AB + RADIUS_RACK)), //Точка C.
                   new THREE.Vector3(Math.cos(ALPHA) * (LENGTH_AB + RADIUS_RACK), LENGTH_AB / 2, -Math.sin(ALPHA) * (LENGTH_AB + RADIUS_RACK)));          //Точка P.
               
               materialCableBCP = new THREE.LineBasicMaterial(colorCableBCP);     //Создаем материал.
               meshCableBCP = new THREE.Line(geometryCableBCP, materialCableBCP); //Создаем объект сцены.
               scene.add(meshCableBCP); //Помещаем кабель на сцену.
           
               //Создаем наконечник стойки AC.
               geometryEndRackAC = new THREE.SphereGeometry(RADIUS_RACK, 32, 32);        //Создаем фигуру (сфера).
               materialEndRackAC = new THREE.MeshBasicMaterial(colorEndRackAC);          //Создаем материал.
               meshEndRackAC = new THREE.Mesh(geometryEndRackAC, materialEndRackAC);     //Создаем объект сцены.
               //Задаем положение центра наконечника.
               meshEndRackAC.position.x = Math.cos(ALPHA) * LENGTH_AB;
               meshEndRackAC.position.y = LENGTH_AB;
               meshEndRackAC.position.z = -Math.sin(ALPHA) * LENGTH_AB;
               scene.add(meshEndRackAC); //Помещаем наконечник на сцену.
               
               //Создаем груз.
               geometryCargoP = new THREE.BoxGeometry(4, 2, 4); //Создаем фигуру (параллелипипед.).
               materialCargoP = new THREE.MeshBasicMaterial(colorCargoP);       //Создаем материал.
               meshCargoP = new THREE.Mesh(geometryCargoP, materialCargoP);     //Создаем объект сцены.
               //Задаем положение центра груза.
               meshCargoP.position.x = Math.cos(ALPHA) * (LENGTH_AB + RADIUS_RACK);
               meshCargoP.position.y = LENGTH_AB / 2;
               meshCargoP.position.z = -Math.sin(ALPHA) * (LENGTH_AB + RADIUS_RACK);
               
               scene.add(meshCargoP); //Помещаем груз на сцену.
               
               //Если вектора усилий нужно отображать.
               if(panelControlOptions.visibleEffort == true) {
                   var tmp = -WEIGHT_P * Math.sqrt(2) * Math.cos(ALPHA); //Усилие на стойку AB.
                   //Создаем вектор усилия стойки AB.
                   vectorEffortAB = new THREE.ArrowHelper(
                       new THREE.Vector3(0, (tmp < 0) ? -1 : 0, 0),                              //Направление.
                       new THREE.Vector3(0, (tmp < 0) ? (-LENGTH_AB / 2) : (LENGTH_AB / 2), 0),  //Координата начала (относительно центра стойки).
                       Math.abs(tmp),                                                            //Длина.
                       colorEffortAB                                                             //Цвет.
                   );
                   meshRackAB.add(vectorEffortAB); //Добавляем вектор усилия к стойке AB.
                   var tmp = WEIGHT_P * (Math.cos(ALPHA) - Math.sin(ALPHA)); //Усилие на стойку BD.
                   //Создаем вектор усилия стойки BD.
                   vectorEffortBD = new THREE.ArrowHelper(
                       new THREE.Vector3(0, (tmp < 0) ? -1 : 1, 0),                                                           //Направление.
                       new THREE.Vector3(0, (tmp < 0) ? -(Math.sqrt(2) * LENGTH_AB / 2) : (Math.sqrt(2) * LENGTH_AB / 2), 0), //Координата начала (относительно центра стойки).
                       Math.abs(tmp),                                                                                         //Длина.
                       colorEffortBD                                                                                          //Цвет.
                   );
                   meshRackBD.add(vectorEffortBD); //Добавляем вектор усилия к стойке BD.
                   var tmp = WEIGHT_P * (Math.cos(ALPHA) + Math.sin(ALPHA)); //Усилие на стойку BE.
                   //Создаем вектор усилия стойки BE.
                   vectorEffortBE = new THREE.ArrowHelper(
                       new THREE.Vector3(0, (tmp < 0) ? -1 : 1, 0),                                                           //Направление.
                       new THREE.Vector3(0, (tmp < 0) ? -(Math.sqrt(2) * LENGTH_AB / 2) : (Math.sqrt(2) * LENGTH_AB / 2), 0), //Координата начала (относительно центра стойки).
                       Math.abs(tmp),                                                                                         //Длина.
                       colorEffortBE                                                                                          //Цвет.
                   );
                   meshRackBE.add(vectorEffortBE); //Добавляем вектор усилия к стойке BE.
               } else {
                   vectorEffortAB = null;
                   vectorEffortBD = null;
                   vectorEffortBE = null;
               }
               
               renderer.render(scene, camera); //Рендинг сцены.
           }
           
           //Функция перерисовки элементов крана на сцене.
           function redrawCraneElements() {
               //Удаляем динамические элементы со сцены.
               scene.remove(meshRackAC);    //Удаление стойки AC.
               scene.remove(meshCableBCP);  //Удаление троса.
               scene.remove(meshEndRackAC); //Удаление наконечника стойки AC.
               scene.remove(meshCargoP);    //Удаление груза.
               if (vectorEffortAB != null) meshRackAB.remove(vectorEffortAB); //Удалили вектор усилия со стойки AB.
               if (vectorEffortBD != null) meshRackBD.remove(vectorEffortBD); //Удалили вектор усилия со стойки BD.
               if (vectorEffortBE != null) meshRackBE.remove(vectorEffortBE); //Удалили вектор усилия со стойки BE.
               
               
               //Добавляем динамические элементы на сцену.
               drawDynamicCraneElements();
           }
           
           
           //Функция рендеринга, вызывается браузером через равные интервалы времени, для
           //перерисовки сцены.
           function render() {
               statFPS.update();
               
               requestAnimationFrame(render);  //Вызвать эту же функцию для рендинга в следующий момент времени (момент времени зависит от браузера).
               renderer.render(scene, camera); //Рендинг сцены.
           }
           
           //Функция, которая вызывается, когда был изменен размер окна.
           function changeSizeWindow() {
               camera.aspect=window.innerWidth/window.innerHeight;
               camera.updateProjectionMatrix();
               renderer.setSize(window.innerWidth,window.innerHeight);
           }
           
           //Функция, которая создает объект: для отображения FPS.
           function initStatFPS()
           {
               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;
           }
           window.onload = init; 
       </script>
   </body>
</html>