Мещерский 48.19
Материал из Department of Theoretical and Applied Mechanics
Версия от 11:09, 22 декабря 2017; Сабина (обсуждение | вклад)
Задача: С помощью языка программирования JavaScript смоделировать планетарный механизм.
Исполнитель: Исаева Сабина
Условие задачи 48.19: Концы однородного тяжелого стержня AB длины 2a и массы M скользят без трения по горизонтальному и вертикальному стержням рамки, вращающейся с постоянной угловой скоростью ω вокруг вертикальной стороны. Составить уравнение движения стержня и определить положение относительного равновесия.
Программа
Код программы
Текст программы на языке JavaScript:
Файл "Zad.js"
1 function init()
2 {
3 scene = new THREE.Scene(); // создаем сцену
4 camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000); // создаем камеру
5
6 renderer = new THREE.WebGLRenderer();
7 renderer.setClearColor(0XEEEEEE,1);
8 renderer.setSize(window.innerWidth,window.innerHeight);
9 renderer.shadowMap.enabled=true;
10
11 axes = new THREE.AxisHelper(20); // создаем координатные оси
12 scene.add(axes);
13
14 control = new THREE.OrbitControls(camera,renderer.domElement);
15
16 controls = new function() // создаем переключатели, позволяющие изменять входные параметры
17 {
18 this.a = 1;
19 this.w = 1;
20 //this.m = 1;
21 this.animate = false;
22 this.reset = function() {
23 controls1.t = 0;
24 controls1.fi = 0;
25 controls1.q = Math.PI/6;
26 controls1.v = 0;
27 controls1.x = 0;
28 ReDraw();
29 }
30 }
31
32 controls1=new function() // вывод полученных в ходе решения задачи значений
33 {
34 this.t = 0.0;
35 this.q = Math.PI/6;
36 this.v = 0;
37 this.x = 0;
38 }
39
40 var gui = new dat.GUI(); // позволяем менять каждый из параметров в определенном диапазоне, в случае изменения вызываем функцию, перестраивающую выводимую на экран картинку
41 gui.add(controls,'a', 1,4).onChange(controls.reset);
42 gui.add(controls,'w',0,20).onChange(ReDraw);
43 gui.add(controls, 'animate');
44 gui.add(controls, 'reset');
45 //gui.add(controls,'m',1,10).onChange(ReDraw);
46 gui.add(controls1, 't').listen();
47 gui.add(controls1, 'q').listen();
48 gui.add(controls1, 'v').listen();
49
50 ambientLight=new THREE.AmbientLight(0x000000);
51 scene.add(ambientLight);
52 document.getElementById("WebGL").appendChild(renderer.domElement);
53 camera.position.x = 0; // задаем местоположение камеры
54 camera.position.y = 0;
55 camera.position.z = 20;
56 camera.lookAt(0,0,0);
57 spotLight=new THREE.SpotLight(0xffffff);
58 spotLight.position.set(90,45,90);
59 scene.add(spotLight);
60 stats = initStats();
61 Draw();
62 renderScene();
63
64 window.addEventListener('resize',onResize,false);
65 };
66
67 function ReDraw() // функция, перерисовывающая всю картинку
68 {
69 scene.remove(ramka);
70 scene.remove(stick);
71 scene.remove(cube1);
72 scene.remove(cube2);
73 Draw();
74 }
75
76 function Draw()
77 {
78 // рамка
79 ramka = new THREE.Group();
80 var ramkaMaterial = new THREE.MeshLambertMaterial({color: 0xffaaff, wireframe:false});
81 var cyl1 = new THREE.Mesh(new THREE.CylinderGeometry(0.2,0.2,20,10),ramkaMaterial);
82 var cyl2 = new THREE.Mesh(new THREE.CylinderGeometry(0.2,0.2,8,10),ramkaMaterial);
83 cyl2.position.set(9.8*Math.cos(controls1.v),0,9.8*Math.sin(controls1.v));
84 var cyl3 = new THREE.Mesh(new THREE.CylinderGeometry(0.2,0.2,10,10),ramkaMaterial);
85 cyl3.rotation.set(0,-controls1.v,Math.PI/2);
86 cyl3.position.set(5*Math.cos(controls1.v),4,5*Math.sin(controls1.v));
87 var cyl4 = new THREE.Mesh(new THREE.CylinderGeometry(0.2,0.2,10,10),ramkaMaterial);
88 cyl4.rotation.set(0,-controls1.v,Math.PI/2);
89 cyl4.position.set(5*Math.cos(controls1.v),-4,5*Math.sin(controls1.v));
90 ramka.add(cyl1);
91 ramka.add(cyl2);
92 ramka.add(cyl3);
93 ramka.add(cyl4);
94 scene.add(ramka);
95 // палка
96 stick = new THREE.Mesh(new THREE.CylinderGeometry(0.2,0.2,2*controls.a,10), new THREE.MeshLambertMaterial({color: 0xff0000}));
97 stick.position.set(((controls.a)*Math.sin(controls1.q)+0.2+controls1.x)*Math.cos(controls1.v), (controls.a)*Math.cos(controls1.q)-4+0.2, ((controls.a)*Math.sin(controls1.q)+0.2+controls1.x)*Math.sin(controls1.v));
98 stick.rotation.set(0,-controls1.v,controls1.q);
99 scene.add(stick);
100
101 // заделка
102 cubeGeometry = new THREE.CubeGeometry(4,1,4);
103 cubeMaterial = new THREE.MeshLambertMaterial({color:0xcccccc});
104 cube1 = new THREE.Mesh(cubeGeometry,cubeMaterial);
105 cube1.position.set(0,10,0);
106 scene.add(cube1);
107 cube2 = new THREE.Mesh(cubeGeometry,cubeMaterial);
108 cube2.position.set(0,-10,0);
109 scene.add(cube2);
110
111 renderer.render(scene,camera);
112 }
113
114 function renderScene()
115 {
116 if (controls.animate)
117 {
118 controls1.t+=dt;
119 controls1.v += controls.w*dt;
120 if (controls1.q<=Math.PI/2) {controls1.q += (0.75*Math.cos(controls1.q)*Math.sin(controls1.q)*controls.w*controls.w+0.75*g/controls.a*Math.sin(controls1.q))*dt*dt}
121 else if ((controls.a)*Math.sin(controls1.q)+0.2+controls1.x<9.8-controls.a) {controls1.x += controls.w*((controls.a)*Math.sin(controls1.q)+0.2+controls1.x)*dt*dt/2}
122 ReDraw();
123 }
124 stats.update();
125 requestAnimationFrame(renderScene);
126 renderer.render(scene,camera);
127 };
128
129 function initStats()
130 {
131 var stats=new Stats();
132 stats.setMode(0);
133 stats.domElement.style.position='0px';
134 stats.domElement.style.left='0px';
135 stats.domElement.style.top='0px';
136 document.getElementById("Stats-output").appendChild(stats.domElement);
137 return stats;
138 };
139
140 function onResize()
141 {
142 camera.aspect=window.innerWidth/window.innerHeight;
143 camera.updateProjectionMatrix();
144 renderer.setSize(window.innerWidth,window.innerHeight);
145 }
146
147 window.onload = init;
148 }
Используемые библиотеки
- three.js
- stats.js
- dat.gui.js
- OrbitControls.js
Решение
В данной задаче у нас присутствует потенциальные и обожженные силы. Рассмотрим кинетическую энергию системы:
Запишем уравнение Лагранжа 2 рода:
Найдём отдельно:
Подставляем в уравнение Лагранжа:
Уравнение движения: