Мещерский 48.7 — различия между версиями
Материал из Department of Theoretical and Applied Mechanics
(Новая страница: «'''''Задача:''''' С помощью языка программирования JavaScript смоделировать планетарный механиз…») |
|||
Строка 1: | Строка 1: | ||
'''''Задача:''''' С помощью языка программирования JavaScript смоделировать планетарный механизм. | '''''Задача:''''' С помощью языка программирования JavaScript смоделировать планетарный механизм. | ||
− | [[File: | + | [[File:Mechanizm.png|thumb|Система трех цилиндрических блоков, соединенных кривошипом]] |
Условие задачи 48.7: | Условие задачи 48.7: | ||
Строка 12: | Строка 12: | ||
<div class="mw-collapsible mw-collapsed"> | <div class="mw-collapsible mw-collapsed"> | ||
'''Текст программы на языке JavaScript:''' <div class="mw-collapsible-content"> | '''Текст программы на языке JavaScript:''' <div class="mw-collapsible-content"> | ||
− | Файл '''" | + | Файл '''"Zad.js"''' |
<syntaxhighlight lang="javascript" line start="1" enclose="div"> | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
function main()//zadachA 48.7 | function main()//zadachA 48.7 | ||
− | { | + | { |
+ | var stats = initStats(); | ||
+ | |||
+ | //Сцена | ||
var scene = new THREE.Scene(); | var scene = new THREE.Scene(); | ||
− | + | ||
− | + | //Камера | |
− | + | var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight , 0.1, 1000); | |
− | + | ||
+ | //Визуализатор | ||
+ | var webGLRenderer = new THREE.WebGLRenderer(); | ||
+ | webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0)); | ||
+ | webGLRenderer.setSize(window.innerWidth, window.innerHeight); | ||
+ | webGLRenderer.shadowMapEnabled = true; | ||
+ | |||
+ | var floorTex = THREE.ImageUtils.loadTexture("floor-wood.jpg") | ||
+ | var plane = new THREE.Mesh(new THREE.CubeGeometry(50, 25, 0.1, 30), new THREE.MeshPhongMaterial({color: 0x3c3c3c, map: floorTex})); | ||
+ | |||
+ | plane.rotation.x=-0.5*Math.PI;//Поворот | ||
+ | plane.position.y = -10; | ||
+ | plane.position.z = -14.5; | ||
+ | scene.add(plane);//Добавили плоскость | ||
+ | plane.receiveShadow = true; | ||
+ | var spotLight = new THREE.SpotLight( 0xffffff ); | ||
+ | spotLight.position.set( 0, 200, 200 ); //-40, 60, -10 | ||
+ | spotLight.castShadow = true; | ||
+ | scene.add(spotLight); | ||
− | var | + | var ambientLight = new THREE.AmbientLight(0x0c0c0c); |
− | + | scene.add(ambientLight); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | //Неподвижный диск | ||
+ | var cylinder1 = createMesh(new THREE.CylinderGeometry(5, 5, 3, 30, 30)); | ||
+ | cylinder1.rotation.x = -0.5*Math.PI; | ||
+ | cylinder1.castShadow = true; | ||
− | var | + | //1 диск |
− | var | + | var cylinder2 = createMesh(new THREE.CylinderGeometry(5, 5, 3, 30, 30)); |
− | var | + | cylinder2.position.x = 10; |
− | + | cylinder2.rotation.x = -0.5*Math.PI; | |
− | + | cylinder2.castShadow = true; | |
+ | |||
+ | //2 диск | ||
+ | var cylinder3 = createMesh(new THREE.CylinderGeometry(5, 5, 3, 30, 30)); | ||
+ | cylinder3.position.x = 20; | ||
+ | cylinder3.rotation.x = -0.5*Math.PI; | ||
+ | cylinder3.castShadow = true; | ||
+ | |||
+ | //Рукоятка | ||
+ | var cylinder4 = createMesh(new THREE.CylinderGeometry(0.3, 0.3, 20, 30, 30)); | ||
+ | cylinder4.position.x = 10; | ||
+ | cylinder4.position.z = 1.5; | ||
+ | cylinder4.rotation.z = -0.5*Math.PI; | ||
+ | cylinder4.castShadow = true; | ||
+ | |||
+ | //Опора неподвижного диска | ||
+ | var cylinder5 = createMesh(new THREE.CylinderGeometry(2, 2, 35, 4, 4)); | ||
+ | cylinder5.position.y = -14.5; | ||
+ | cylinder5.position.z = -3.5; | ||
+ | cylinder5.rotation.y = 0.25*Math.PI; | ||
+ | cylinder5.castShadow = true; | ||
− | var | + | //Перемычка |
− | + | var cylinder6 = createMesh(new THREE.CylinderGeometry(0.3, 0.3, 3, 30, 30)); | |
− | + | cylinder6.position.z = -1.5; | |
− | + | cylinder6.rotation.x = -0.5*Math.PI; | |
− | |||
− | |||
− | |||
− | + | //Вектора скоростей | |
− | + | var vectorMaterial = new THREE.MeshLambertMaterial({color: 0x00ee22}); | |
− | |||
− | |||
− | |||
− | + | var vector1lineGeometry = new THREE.CylinderGeometry(0.1, 0.1, 10, 30, 30); | |
− | + | var vector1line = new THREE.Mesh(vector1lineGeometry, vectorMaterial); | |
+ | vector1line.position.x = 20; | ||
+ | vector1line.position.y = 5; | ||
+ | vector1line.position.z = 1.5; | ||
+ | var vector1Geometry = new THREE.CylinderGeometry(0, 0.2, 1, 30, 30); | ||
+ | var vector1 = new THREE.Mesh(vector1Geometry, vectorMaterial); | ||
+ | vector1.position.x = 20; | ||
+ | vector1.position.y = 10; | ||
+ | vector1.position.z = 1.5; | ||
− | var | + | var vector2lineGeometry = new THREE.CylinderGeometry(0.1, 0.1, 5, 30, 30); |
− | + | var vector2line = new THREE.Mesh(vector2lineGeometry, vectorMaterial); | |
− | + | vector2line.position.x = 10; | |
− | var | + | vector2line.position.y = 2.5; |
− | + | vector2line.position.z = 1.5; | |
− | |||
− | + | var vector2Geometry = new THREE.CylinderGeometry(0, 0.2, 1, 30, 30); | |
+ | var vector2 = new THREE.Mesh(vector2Geometry, vectorMaterial); | ||
+ | vector2.position.x = 10; | ||
+ | vector2.position.y = 5.5; | ||
+ | vector2.position.z = 1.5; | ||
− | + | //Группа подвижных объектов | |
− | + | var group1 = new THREE.Object3D(); | |
− | + | group1.add(cylinder2); | |
− | + | group1.add(cylinder3); | |
− | + | group1.add(cylinder4); | |
+ | group1.add(vector1line); | ||
+ | group1.add(vector1); | ||
+ | group1.add(vector2line); | ||
+ | group1.add(vector2); | ||
+ | group1.position.y = 22; | ||
+ | scene.add(group1); | ||
+ | //Группа неподвижных объектов | ||
+ | var group2 = new THREE.Object3D(); | ||
+ | group2.add(cylinder1); | ||
+ | group2.add(cylinder5); | ||
+ | group2.add(cylinder6); | ||
+ | group2.position.y = 22; | ||
+ | scene.add(group2); | ||
+ | function createMesh(geom) { | ||
+ | var texture = THREE.ImageUtils.loadTexture("bathroom.jpg") | ||
+ | var mat = new THREE.MeshPhongMaterial(); | ||
+ | mat.map = texture; | ||
− | camera.position.x= | + | var mesh = new THREE.Mesh(geom, mat); |
− | camera.position.y= | + | |
− | camera.position.z= | + | return mesh; |
− | camera.lookAt(scene.position); | + | } |
− | + | ||
+ | camera.position.x = -150; | ||
+ | camera.position.y = 180; | ||
+ | camera.position.z = 200; | ||
+ | camera.lookAt(scene.position);//Камера смотрит на сцену | ||
+ | $("#WebGL-output").append(webGLRenderer.domElement); | ||
+ | webGLRenderer.render(scene, camera); | ||
+ | //Контроль камеры | ||
+ | cameraControls = new THREE.OrbitControls(camera, webGLRenderer.domElement); | ||
+ | cameraControls.maxDistance = 150; | ||
+ | cameraControls.minDistance = 0.5; | ||
+ | cameraControls.update(); | ||
var controls = new function() { | var controls = new function() { | ||
− | this. | + | this.Massa = 25; |
+ | this.Moment = 5; | ||
+ | this.Radius = 1; | ||
+ | this.Boost = this.Moment/(22*this.Massa*this.Radius*this.Radius); | ||
+ | this.Stop = function() { | ||
+ | this.Moment = 0; | ||
+ | } | ||
+ | this.Redraw = function(){ | ||
+ | step = 0; | ||
+ | |||
+ | this.Radius = 1; | ||
+ | |||
+ | cylinder2.rotation.y = 0; | ||
+ | cylinder3.rotation.y = 0; | ||
+ | group1.rotation.z = 0; | ||
+ | } | ||
+ | |||
+ | |||
+ | var gui = new dat.GUI(); | ||
+ | gui.add(controls, 'Massa',0,50); | ||
+ | gui.add(controls, 'Moment',0,20); | ||
+ | gui.add(controls, 'Radius',0.1,10).onChange(function (e) { | ||
+ | cylinder1.scale.set(e, 1, e) | ||
+ | cylinder2.scale.set(e, 1, e) | ||
+ | cylinder3.scale.set(e, 1, e) | ||
+ | cylinder2.position.set(e*10, 0, 0) | ||
+ | cylinder3.position.set(e*20, 0, 0) | ||
+ | cylinder4.scale.set(e, e, e) | ||
+ | cylinder4.position.set(e*10, 0, 1.5) | ||
− | + | vector1line.scale.set(1, e, 1) | |
− | + | vector1.scale.set(1, e, 1) | |
− | + | vector1line.position.set(e*20, e*5, 1.5) | |
− | + | vector1.position.set(e*20, e*10, 1.5) | |
− | + | ||
− | + | vector2line.scale.set(1, e, 1) | |
− | + | vector2.scale.set(1, e, 1) | |
− | + | vector2line.position.set(e*10, e*2.5, 1.5) | |
− | + | vector2.position.set(e*10, e*5, 1.5) | |
− | + | }); | |
− | + | gui.add(controls, 'Boost').listen(); | |
− | + | gui.add(controls, 'Stop'); | |
− | + | gui.add(controls, 'Redraw'); | |
− | |||
− | |||
− | |||
var step = 0; | var step = 0; | ||
− | + | function render() { | |
− | + | stats.update(); | |
− | + | requestAnimationFrame(render); | |
− | + | webGLRenderer.render(scene, camera); | |
− | + | if (step<50){ | |
− | function | + | step += 0.01; |
− | + | ||
− | + | controls.Boost = controls.Moment/(22*controls.Massa*controls.Radius*controls.Radius); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | cylinder2.rotation.y -= 1/4*controls.Boost*step*step; | |
− | + | cylinder3.rotation.y += 1/4*controls.Boost*step*step; | |
− | + | group1.rotation.z += 1/4*controls.Boost*step*step; | |
− | + | } | |
− | + | else { | |
− | + | step = 50 | |
− | + | ||
− | + | controls.Boost = controls.Moment/(22*controls.Massa*controls.Radius*controls.Radius); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | cylinder2.rotation.y -= 1/4*controls.Boost*step*step; | |
− | + | cylinder3.rotation.y += 1/4*controls.Boost*step*step; | |
− | + | group1.rotation.z += 1/4*controls.Boost*step*step; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | render(); | ||
+ | |||
+ | function initStats() { | ||
+ | var stats = new Stats(); | ||
+ | stats.setMode(0); // 0: fps, 1: ms | ||
+ | stats.domElement.style.position = 'absolute'; | ||
+ | stats.domElement.style.left = '0px'; | ||
+ | stats.domElement.style.top = '0px'; | ||
+ | $("#Stats-output").append(stats.domElement); | ||
+ | return stats; | ||
+ | } | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Строка 224: | Строка 242: | ||
== Используемые библиотеки == | == Используемые библиотеки == | ||
+ | * three.js | ||
+ | * jquery-1.9.0.js | ||
+ | * stats.js | ||
* dat.gui.js | * dat.gui.js | ||
− | * | + | * OrbitControls.js |
− | |||
== Уравнения == | == Уравнения == |
Версия 19:34, 20 декабря 2017
Задача: С помощью языка программирования JavaScript смоделировать планетарный механизм.
Условие задачи 48.7: В планетарном механизме колесо с осью O1 неподвижно; к рукоятке O1O3 приложен вращающий момент M; механизм расположен в горизонтальной плоскости. Определить угловое ускорение рукоятки, считая колеса однородными дисками с одинаковыми массами m и радиусами r и пренебрегая массой рукоятки.
Решение
Текст программы на языке JavaScript:
Файл "Zad.js"
1 function main()//zadachA 48.7
2 {
3 var stats = initStats();
4
5 //Сцена
6 var scene = new THREE.Scene();
7
8 //Камера
9 var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight , 0.1, 1000);
10
11 //Визуализатор
12 var webGLRenderer = new THREE.WebGLRenderer();
13 webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
14 webGLRenderer.setSize(window.innerWidth, window.innerHeight);
15 webGLRenderer.shadowMapEnabled = true;
16
17 var floorTex = THREE.ImageUtils.loadTexture("floor-wood.jpg")
18 var plane = new THREE.Mesh(new THREE.CubeGeometry(50, 25, 0.1, 30), new THREE.MeshPhongMaterial({color: 0x3c3c3c, map: floorTex}));
19
20 plane.rotation.x=-0.5*Math.PI;//Поворот
21 plane.position.y = -10;
22 plane.position.z = -14.5;
23 scene.add(plane);//Добавили плоскость
24 plane.receiveShadow = true;
25
26 var spotLight = new THREE.SpotLight( 0xffffff );
27 spotLight.position.set( 0, 200, 200 ); //-40, 60, -10
28 spotLight.castShadow = true;
29 scene.add(spotLight);
30
31 var ambientLight = new THREE.AmbientLight(0x0c0c0c);
32 scene.add(ambientLight);
33
34 //Неподвижный диск
35 var cylinder1 = createMesh(new THREE.CylinderGeometry(5, 5, 3, 30, 30));
36 cylinder1.rotation.x = -0.5*Math.PI;
37 cylinder1.castShadow = true;
38
39 //1 диск
40 var cylinder2 = createMesh(new THREE.CylinderGeometry(5, 5, 3, 30, 30));
41 cylinder2.position.x = 10;
42 cylinder2.rotation.x = -0.5*Math.PI;
43 cylinder2.castShadow = true;
44
45 //2 диск
46 var cylinder3 = createMesh(new THREE.CylinderGeometry(5, 5, 3, 30, 30));
47 cylinder3.position.x = 20;
48 cylinder3.rotation.x = -0.5*Math.PI;
49 cylinder3.castShadow = true;
50
51 //Рукоятка
52 var cylinder4 = createMesh(new THREE.CylinderGeometry(0.3, 0.3, 20, 30, 30));
53 cylinder4.position.x = 10;
54 cylinder4.position.z = 1.5;
55 cylinder4.rotation.z = -0.5*Math.PI;
56 cylinder4.castShadow = true;
57
58 //Опора неподвижного диска
59 var cylinder5 = createMesh(new THREE.CylinderGeometry(2, 2, 35, 4, 4));
60 cylinder5.position.y = -14.5;
61 cylinder5.position.z = -3.5;
62 cylinder5.rotation.y = 0.25*Math.PI;
63 cylinder5.castShadow = true;
64
65 //Перемычка
66 var cylinder6 = createMesh(new THREE.CylinderGeometry(0.3, 0.3, 3, 30, 30));
67 cylinder6.position.z = -1.5;
68 cylinder6.rotation.x = -0.5*Math.PI;
69
70 //Вектора скоростей
71 var vectorMaterial = new THREE.MeshLambertMaterial({color: 0x00ee22});
72
73 var vector1lineGeometry = new THREE.CylinderGeometry(0.1, 0.1, 10, 30, 30);
74 var vector1line = new THREE.Mesh(vector1lineGeometry, vectorMaterial);
75 vector1line.position.x = 20;
76 vector1line.position.y = 5;
77 vector1line.position.z = 1.5;
78
79 var vector1Geometry = new THREE.CylinderGeometry(0, 0.2, 1, 30, 30);
80 var vector1 = new THREE.Mesh(vector1Geometry, vectorMaterial);
81 vector1.position.x = 20;
82 vector1.position.y = 10;
83 vector1.position.z = 1.5;
84
85 var vector2lineGeometry = new THREE.CylinderGeometry(0.1, 0.1, 5, 30, 30);
86 var vector2line = new THREE.Mesh(vector2lineGeometry, vectorMaterial);
87 vector2line.position.x = 10;
88 vector2line.position.y = 2.5;
89 vector2line.position.z = 1.5;
90
91 var vector2Geometry = new THREE.CylinderGeometry(0, 0.2, 1, 30, 30);
92 var vector2 = new THREE.Mesh(vector2Geometry, vectorMaterial);
93 vector2.position.x = 10;
94 vector2.position.y = 5.5;
95 vector2.position.z = 1.5;
96
97 //Группа подвижных объектов
98 var group1 = new THREE.Object3D();
99 group1.add(cylinder2);
100 group1.add(cylinder3);
101 group1.add(cylinder4);
102 group1.add(vector1line);
103 group1.add(vector1);
104 group1.add(vector2line);
105 group1.add(vector2);
106 group1.position.y = 22;
107 scene.add(group1);
108
109 //Группа неподвижных объектов
110 var group2 = new THREE.Object3D();
111 group2.add(cylinder1);
112 group2.add(cylinder5);
113 group2.add(cylinder6);
114 group2.position.y = 22;
115 scene.add(group2);
116
117 function createMesh(geom) {
118 var texture = THREE.ImageUtils.loadTexture("bathroom.jpg")
119 var mat = new THREE.MeshPhongMaterial();
120 mat.map = texture;
121
122 var mesh = new THREE.Mesh(geom, mat);
123
124 return mesh;
125 }
126
127 camera.position.x = -150;
128 camera.position.y = 180;
129 camera.position.z = 200;
130 camera.lookAt(scene.position);//Камера смотрит на сцену
131
132 $("#WebGL-output").append(webGLRenderer.domElement);
133 webGLRenderer.render(scene, camera);
134
135 //Контроль камеры
136 cameraControls = new THREE.OrbitControls(camera, webGLRenderer.domElement);
137 cameraControls.maxDistance = 150;
138 cameraControls.minDistance = 0.5;
139 cameraControls.update();
140
141 var controls = new function() {
142 this.Massa = 25;
143 this.Moment = 5;
144 this.Radius = 1;
145 this.Boost = this.Moment/(22*this.Massa*this.Radius*this.Radius);
146 this.Stop = function() {
147 this.Moment = 0;
148 }
149 this.Redraw = function(){
150 step = 0;
151
152 this.Radius = 1;
153
154 cylinder2.rotation.y = 0;
155 cylinder3.rotation.y = 0;
156 group1.rotation.z = 0;
157 }
158
159
160 var gui = new dat.GUI();
161 gui.add(controls, 'Massa',0,50);
162 gui.add(controls, 'Moment',0,20);
163 gui.add(controls, 'Radius',0.1,10).onChange(function (e) {
164 cylinder1.scale.set(e, 1, e)
165 cylinder2.scale.set(e, 1, e)
166 cylinder3.scale.set(e, 1, e)
167 cylinder2.position.set(e*10, 0, 0)
168 cylinder3.position.set(e*20, 0, 0)
169 cylinder4.scale.set(e, e, e)
170 cylinder4.position.set(e*10, 0, 1.5)
171
172 vector1line.scale.set(1, e, 1)
173 vector1.scale.set(1, e, 1)
174 vector1line.position.set(e*20, e*5, 1.5)
175 vector1.position.set(e*20, e*10, 1.5)
176
177 vector2line.scale.set(1, e, 1)
178 vector2.scale.set(1, e, 1)
179 vector2line.position.set(e*10, e*2.5, 1.5)
180 vector2.position.set(e*10, e*5, 1.5)
181 });
182 gui.add(controls, 'Boost').listen();
183 gui.add(controls, 'Stop');
184 gui.add(controls, 'Redraw');
185
186 var step = 0;
187
188 function render() {
189 stats.update();
190 requestAnimationFrame(render);
191 webGLRenderer.render(scene, camera);
192 if (step<50){
193 step += 0.01;
194
195 controls.Boost = controls.Moment/(22*controls.Massa*controls.Radius*controls.Radius);
196
197 cylinder2.rotation.y -= 1/4*controls.Boost*step*step;
198 cylinder3.rotation.y += 1/4*controls.Boost*step*step;
199 group1.rotation.z += 1/4*controls.Boost*step*step;
200 }
201 else {
202 step = 50
203
204 controls.Boost = controls.Moment/(22*controls.Massa*controls.Radius*controls.Radius);
205
206 cylinder2.rotation.y -= 1/4*controls.Boost*step*step;
207 cylinder3.rotation.y += 1/4*controls.Boost*step*step;
208 group1.rotation.z += 1/4*controls.Boost*step*step;
209 }
210 }
211
212 render();
213
214 function initStats() {
215 var stats = new Stats();
216 stats.setMode(0); // 0: fps, 1: ms
217 stats.domElement.style.position = 'absolute';
218 stats.domElement.style.left = '0px';
219 stats.domElement.style.top = '0px';
220 $("#Stats-output").append(stats.domElement);
221 return stats;
222 }
223 }
Используемые библиотеки
- three.js
- jquery-1.9.0.js
- stats.js
- dat.gui.js
- OrbitControls.js
Уравнения
Если центр неподвижной окружности находится в начале координат, её радиус равен
, радиус катящейся по ней окружности равен , то эпициклоида описывается параметрическими уравнениями относительно :где угол поворота точки, описывающей эпициклоиду, относительно центра неподвижной окружности, — параметр, но фактически это угол наклона отрезка между центрами к оси .
—Можно ввести величину
, тогда уравнения предстанут в виде