Планетарный механизм — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Решение)
 
(не показано 9 промежуточных версий этого же участника)
Строка 1: Строка 1:
 
'''''Задача:''''' С помощью языка программирования JavaScript смоделировать планетарный механизм.
 
'''''Задача:''''' С помощью языка программирования JavaScript смоделировать планетарный механизм.
 
[[File:Untitled.jpg|thumb|Система двух цилиндрических блоков, соединенных кривошипом]]
 
[[File:Untitled.jpg|thumb|Система двух цилиндрических блоков, соединенных кривошипом]]
 +
 +
== Решение ==
 +
 +
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/filimonov/TMtrajectory.html |width=900 |height=450 |border=0 }}
 +
 +
Программа: [[Медиа:TM.zip|скачать]]
 +
 +
<div class="mw-collapsible mw-collapsed">
 +
'''Текст программы на языке JavaScript:''' <div class="mw-collapsible-content">
 +
Файл '''"TMtrajectory.js"'''
 +
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 +
function main()
 +
{
 +
var scene = new THREE.Scene();
 +
var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
 +
var render = new THREE.WebGLRenderer();
 +
render.setClearColor(0xFFFFFF, 1);
 +
render.setSize(window.innerWidth, window.innerHeight);
 +
 +
 +
var geometry = new THREE.CylinderGeometry( 1, 1, 5, 32 );
 +
var material = new THREE.MeshBasicMaterial( {color: 0x000000, wireframe:true} );
 +
var cylinder1 = new THREE.Mesh( geometry, material );
 +
scene.add( cylinder1 );
 +
var geometry = new THREE.CylinderGeometry( 1, 1, 5, 32 );
 +
var material = new THREE.MeshBasicMaterial( {color: 0x000000, wireframe:true} );
 +
var cylinder = new THREE.Mesh( geometry, material );
 +
scene.add( cylinder );
 +
cylinder1.position.x=0;
 +
cylinder1.position.y=2.5;
 +
cylinder1.position.z=0;
 +
cylinder.position.x=20;
 +
cylinder.position.y=2.5;
 +
cylinder.position.z=0;
 +
scene.add(cylinder);
 +
 +
 +
var geometry = new THREE.BoxGeometry( 20, 0.5, 0.5 );
 +
var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
 +
var cube = new THREE.Mesh( geometry, material );
 +
scene.add( cube );
 +
cube.position.x=10;
 +
cube.position.y=5;
 +
cube.position.z=0;
 +
/**cube.position.x=-4;
 +
cube.position.y=3;
 +
cube.position.z=0;
 +
scene.add(cube);*/
 +
 +
 +
var sphereGeometry = new THREE.SphereGeometry(0.5,20,20);
 +
var sphereMaterial = new THREE.MeshLambertMaterial({color:0x7777ff, wireframe:false});
 +
var ball = new THREE.Mesh(sphereGeometry, sphereMaterial)
 +
 +
scene.add(ball);
 +
 +
var sphereGeometry = new THREE.SphereGeometry(0.5,20,20);
 +
var sphereMaterial = new THREE.MeshLambertMaterial({color:0x0000ff, wireframe:false});
 +
var ball1 = new THREE.Mesh(sphereGeometry, sphereMaterial)
 +
 +
scene.add(ball1);
 +
 +
 +
var  spotLight = new THREE.SpotLight(0xffffff);
 +
spotLight.position.set(10,30,30)
 +
scene.add(spotLight);
 +
 +
var  spotLight1 = new THREE.SpotLight(0xffffff);
 +
spotLight.position.set(10,10,0)
 +
scene.add(spotLight1);
 +
 +
render.shadowMapEnabled = true;
 +
spotLight.castShadow = true;
 +
spotLight1.castShadow = true;
 +
 +
 +
 +
 +
camera.position.x= 0;
 +
camera.position.y= 80;
 +
camera.position.z= 0;
 +
camera.lookAt(scene.position);
 +
$("#webGL").append(render.domElement);
 +
 +
 +
 +
var controls = new function() {
 +
this.rotationSpeed = 0.01;
 +
this.Radius = 5;
 +
}
 +
var gui = new dat.GUI();
 +
gui.add(controls, 'rotationSpeed',0,0.5);
 +
gui.add(controls,'Radius',1,15);
 +
 +
 +
 +
control1 = new THREE.OrbitControls(camera);
 +
control1.dumping = 0.2;
 +
 +
 +
/**window.addEventListener('resize',onWindowResize,false);
 +
function onWindowResize()
 +
{
 +
camera.aspect = window.innerWidth/window.innerHeight;
 +
camera.updateProjectionMatrix();
 +
render.setSize(window.innerWidth,window.innerHeight);
 +
 +
renderer();
 +
}*/
 +
 +
var trajectoryGeometry = new THREE.SphereGeometry(0.05, 16, 16);
 +
var trajectoryMaterial = new THREE.MeshBasicMaterial( {color: 0x000000,wireframe:true} );
 +
 +
var trajectoryGeometry1 = new THREE.SphereGeometry(0.05, 16, 16);
 +
var trajectoryMaterial1 = new THREE.MeshBasicMaterial( {color: 0x0000ff,wireframe:true} );
 +
 +
var stats = initStats();
 +
var step = 0;
 +
 +
 +
 +
renderer();
 +
function renderer()
 +
{
 +
stats.update();
 +
 +
var r=20-controls.Radius;
 +
var k = r/controls.Radius;
 +
 +
var r1=(20-controls.Radius)+controls.Radius/4;
 +
var k1 = (r1)/(controls.Radius*0.5);
 +
 +
cylinder.position.x=20*(Math.cos(step));
 +
cylinder.position.z=20*(Math.sin(step));
 +
step+=controls.rotationSpeed*0.3;
 +
 +
 +
 +
cylinder.rotation.y-=controls.rotationSpeed;
 +
cube.position.x=10*(Math.cos(step));
 +
cube.position.z=10*(Math.sin(step));
 +
cube.rotation.y-=controls.rotationSpeed*0.3;
 +
requestAnimationFrame(renderer);
 +
control1.update();
 +
cylinder.scale.set(controls.Radius,1,controls.Radius);
 +
cylinder1.scale.set(20-controls.Radius,1,20-controls.Radius);
 +
render.render(scene,camera);
 +
ball.position.x = controls.Radius*(k+1)*(Math.cos(step)-(Math.cos((k+1)*step))/(k+1));
 +
ball.position.z = controls.Radius*(k+1)*(Math.sin(step)-(Math.sin((k+1)*step))/(k+1));
 +
ball.position.y = 5;
 +
 +
ball1.position.x = 0.5*controls.Radius*(k1+1)*(Math.cos(step)-(Math.cos((k1+1)*step))/(k1+1));
 +
ball1.position.z = 0.5*controls.Radius*(k1+1)*(Math.sin(step)-(Math.sin((k1+1)*step))/(k1+1));
 +
ball1.position.y = 5;
 +
 +
var trajectory = new THREE.Mesh(trajectoryGeometry, trajectoryMaterial);
 +
trajectory.position.x = ball.position.x;
 +
trajectory.position.y = 5;
 +
trajectory.position.z = ball.position.z;
 +
 +
var trajectory1 = new THREE.Mesh(trajectoryGeometry1, trajectoryMaterial1);
 +
trajectory1.position.x = ball1.position.x;
 +
trajectory1.position.y = 5;
 +
trajectory1.position.z = ball1.position.z;
 +
 +
scene.add( trajectory );
 +
scene.add( trajectory1 );
 +
 +
}
 +
 +
      this.start = renderer;
 +
}
 +
function initStats()
 +
{
 +
var stats = new Stats();
 +
stats.setMode(0);
 +
stats.domElement.style.position='absolute';
 +
stats.domElement.style.left = '0px';
 +
stats.domElement.style.top = '0px';
 +
$("#Stats").append(stats.domElement);
 +
return stats;
 +
}
 +
</syntaxhighlight>
 +
</div>
 +
 +
== Используемые библиотеки ==
 +
 +
* cloudflare.js
 +
* dat.gui.js
 +
* googleapis.js
 +
* orbitControls.js
 +
* stats.js
 +
* trackballControls.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>

Текущая версия на 12:51, 26 мая 2015

Задача: С помощью языка программирования JavaScript смоделировать планетарный механизм.

Система двух цилиндрических блоков, соединенных кривошипом

Решение[править]

Программа: скачать

Текст программы на языке JavaScript:

Файл "TMtrajectory.js"

  1 function main()
  2 {	
  3 	var scene = new THREE.Scene();
  4 	var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
  5 	var render = new THREE.WebGLRenderer();
  6 	render.setClearColor(0xFFFFFF, 1);
  7 	render.setSize(window.innerWidth, window.innerHeight);
  8 	
  9 	
 10 	var geometry = new THREE.CylinderGeometry( 1, 1, 5, 32 );
 11 	var material = new THREE.MeshBasicMaterial( {color: 0x000000, wireframe:true} );
 12 	var cylinder1 = new THREE.Mesh( geometry, material );
 13 	scene.add( cylinder1 );
 14 	var geometry = new THREE.CylinderGeometry( 1, 1, 5, 32 );
 15 	var material = new THREE.MeshBasicMaterial( {color: 0x000000, wireframe:true} );
 16 	var cylinder = new THREE.Mesh( geometry, material );
 17 	scene.add( cylinder );
 18 	cylinder1.position.x=0;
 19 	cylinder1.position.y=2.5;
 20 	cylinder1.position.z=0;
 21 	cylinder.position.x=20;
 22 	cylinder.position.y=2.5;
 23 	cylinder.position.z=0;
 24 	scene.add(cylinder);
 25 	
 26 	
 27 	var geometry = new THREE.BoxGeometry( 20, 0.5, 0.5 );
 28 	var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
 29 	var cube = new THREE.Mesh( geometry, material );
 30 	scene.add( cube );
 31 	cube.position.x=10;
 32 	cube.position.y=5;
 33 	cube.position.z=0;
 34 	/**cube.position.x=-4;
 35 	cube.position.y=3;
 36 	cube.position.z=0;
 37 	scene.add(cube);*/
 38 	
 39 
 40 	var sphereGeometry = new THREE.SphereGeometry(0.5,20,20);
 41 	var sphereMaterial = new THREE.MeshLambertMaterial({color:0x7777ff, wireframe:false});
 42 	var ball = new THREE.Mesh(sphereGeometry, sphereMaterial)
 43 
 44 	scene.add(ball);
 45 	
 46 	var sphereGeometry = new THREE.SphereGeometry(0.5,20,20);
 47 	var sphereMaterial = new THREE.MeshLambertMaterial({color:0x0000ff, wireframe:false});
 48 	var ball1 = new THREE.Mesh(sphereGeometry, sphereMaterial)
 49 
 50 	scene.add(ball1);
 51 	
 52 	
 53 	var  spotLight = new THREE.SpotLight(0xffffff);
 54 	spotLight.position.set(10,30,30)	
 55 	scene.add(spotLight);
 56 	
 57 	var  spotLight1 = new THREE.SpotLight(0xffffff);
 58 	spotLight.position.set(10,10,0)	
 59 	scene.add(spotLight1);
 60 	
 61 	render.shadowMapEnabled = true;
 62 	spotLight.castShadow = true;
 63 	spotLight1.castShadow = true;
 64 
 65 	
 66 	
 67 	
 68 	camera.position.x= 0;
 69 	camera.position.y= 80;
 70 	camera.position.z= 0;
 71 	camera.lookAt(scene.position);
 72 	$("#webGL").append(render.domElement);
 73 	
 74 	
 75 	
 76 	var controls = new function() {
 77 		this.rotationSpeed = 0.01;
 78 		this.Radius = 5;
 79 	}
 80 	var gui = new dat.GUI();
 81 	gui.add(controls, 'rotationSpeed',0,0.5);
 82 	gui.add(controls,'Radius',1,15);
 83 
 84 
 85 
 86 	control1 = new THREE.OrbitControls(camera);
 87 	control1.dumping = 0.2;
 88 
 89 	
 90 	/**window.addEventListener('resize',onWindowResize,false);
 91 	function onWindowResize()
 92 	{
 93 	camera.aspect = window.innerWidth/window.innerHeight;
 94 	camera.updateProjectionMatrix();
 95 	render.setSize(window.innerWidth,window.innerHeight);
 96 
 97 	renderer();
 98 }*/
 99 
100 	var trajectoryGeometry = new THREE.SphereGeometry(0.05, 16, 16);
101 	var trajectoryMaterial = new THREE.MeshBasicMaterial( {color: 0x000000,wireframe:true} );
102 	
103 	var trajectoryGeometry1 = new THREE.SphereGeometry(0.05, 16, 16);
104 	var trajectoryMaterial1 = new THREE.MeshBasicMaterial( {color: 0x0000ff,wireframe:true} );
105 	
106 	var stats = initStats();
107 	var step = 0;
108 	
109 	
110 	
111 	renderer();
112 	function renderer()
113 	{
114 		stats.update();
115 		
116 		var r=20-controls.Radius;
117 		var k = r/controls.Radius;
118 		
119 		var r1=(20-controls.Radius)+controls.Radius/4;
120 		var k1 = (r1)/(controls.Radius*0.5);
121 	
122 		cylinder.position.x=20*(Math.cos(step));
123 		cylinder.position.z=20*(Math.sin(step));
124 		step+=controls.rotationSpeed*0.3;
125 		
126 		
127 		
128 		cylinder.rotation.y-=controls.rotationSpeed;
129 		cube.position.x=10*(Math.cos(step));
130 		cube.position.z=10*(Math.sin(step));
131 		cube.rotation.y-=controls.rotationSpeed*0.3;
132 		requestAnimationFrame(renderer);
133 		control1.update();
134 		cylinder.scale.set(controls.Radius,1,controls.Radius);
135 		cylinder1.scale.set(20-controls.Radius,1,20-controls.Radius);
136 		render.render(scene,camera);
137 		ball.position.x = controls.Radius*(k+1)*(Math.cos(step)-(Math.cos((k+1)*step))/(k+1));
138 		ball.position.z = controls.Radius*(k+1)*(Math.sin(step)-(Math.sin((k+1)*step))/(k+1));
139 		ball.position.y = 5;
140 		
141 		ball1.position.x = 0.5*controls.Radius*(k1+1)*(Math.cos(step)-(Math.cos((k1+1)*step))/(k1+1));
142 		ball1.position.z = 0.5*controls.Radius*(k1+1)*(Math.sin(step)-(Math.sin((k1+1)*step))/(k1+1));
143 		ball1.position.y = 5;
144 		
145 		var trajectory = new THREE.Mesh(trajectoryGeometry, trajectoryMaterial);
146 		trajectory.position.x = ball.position.x;
147 		trajectory.position.y = 5;
148 		trajectory.position.z = ball.position.z;
149 		
150 		var trajectory1 = new THREE.Mesh(trajectoryGeometry1, trajectoryMaterial1);
151 		trajectory1.position.x = ball1.position.x;
152 		trajectory1.position.y = 5;
153 		trajectory1.position.z = ball1.position.z;
154 			
155 		scene.add( trajectory );
156 		scene.add( trajectory1 );
157 			
158 	}
159 	
160        this.start = renderer;
161 }
162 function initStats()
163 {
164 	var stats = new Stats();
165 	stats.setMode(0);
166 	stats.domElement.style.position='absolute';
167 	stats.domElement.style.left = '0px';
168 	stats.domElement.style.top = '0px';
169 	$("#Stats").append(stats.domElement);
170 	return stats;
171 }

Используемые библиотеки[править]

  • cloudflare.js
  • dat.gui.js
  • googleapis.js
  • orbitControls.js
  • stats.js
  • trackballControls.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]