Мещерский 48.7

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск

Задача: С помощью языка программирования 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

Уравнения

Если центр неподвижной окружности находится в начале координат, её радиус равен [math]R[/math], радиус катящейся по ней окружности равен [math]r[/math], то эпициклоида описывается параметрическими уравнениями относительно [math]\varphi[/math]:

[math]\begin{cases} x = (R + r)\cos\varphi - r\cos(\alpha+\frac{R+r}{r}\varphi) \\ y = (R + r)\sin\varphi - r\sin(\alpha+\frac{R+r}{r}\varphi) \end{cases}[/math]

где [math]\alpha[/math] — угол поворота точки, описывающей эпициклоиду, относительно центра неподвижной окружности, [math]\varphi[/math] — параметр, но фактически это угол наклона отрезка между центрами к оси [math]OX[/math].

Можно ввести величину [math]\textstyle k=\frac{R}{r}[/math], тогда уравнения предстанут в виде

[math]\begin{cases} x = r (k+1) \left( \cos \varphi- \frac{\cos((k+1)\varphi)}{k+1} \right) \\ y = r (k+1) \left( \sin \varphi- \frac{\sin((k+1)\varphi)}{k+1} \right) \end{cases}[/math]