Мещерский 48.7 — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Новая страница: «'''''Задача:''''' С помощью языка программирования JavaScript смоделировать планетарный механиз…»)
 
Строка 1: Строка 1:
 
'''''Задача:''''' С помощью языка программирования JavaScript смоделировать планетарный механизм.
 
'''''Задача:''''' С помощью языка программирования JavaScript смоделировать планетарный механизм.
  
[[File:vpM3.jpg|thumb|Система трех цилиндрических блоков, соединенных кривошипом]]
+
[[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">
Файл '''"48.7.js"'''
+
Файл '''"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 render = new THREE.WebGLRenderer();
+
//Камера
  render.setClearColor(0xFFFFFF, 1);
+
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight , 0.1, 1000);
  render.setSize(800, 400);
+
 +
//Визуализатор
 +
        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 geometry = new THREE.BoxGeometry( 20, 1, 1 );
+
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
    var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
+
        scene.add(ambientLight);
    var cube = new THREE.Mesh( geometry, material );
 
    scene.add( cube );
 
cube.position.x=10;
 
cube.position.y=2.5;
 
cube.position.z=0.5;
 
var geometry = new THREE.CylinderGeometry( 1, 1, 5, 32 );
 
var material = new THREE.MeshBasicMaterial( {color: 0x000000, wireframe:true} );
 
var cylinder2 = new THREE.Mesh( geometry, material );
 
scene.add( cylinder2 );
 
var geometry = new THREE.CylinderGeometry( 1, 1, 5, 32 );
 
var material = new THREE.MeshBasicMaterial( {color: 0x00000, 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=10;
 
cylinder.position.y=2.5;
 
cylinder.position.z=0;
 
cylinder2.position.x=20;
 
cylinder2.position.y=2.5;
 
cylinder2.position.z=0;
 
scene.add(cylinder);
 
 
 
 +
//Неподвижный диск
 +
var cylinder1 = createMesh(new THREE.CylinderGeometry(5, 5, 3, 30, 30));
 +
cylinder1.rotation.x = -0.5*Math.PI;
 +
cylinder1.castShadow = true;
 
 
var sphereGeometry = new THREE.SphereGeometry(0.5,20,20);
+
//1 диск
var sphereMaterial = new THREE.MeshLambertMaterial({color:0x7777ff, wireframe:true});
+
var cylinder2 = createMesh(new THREE.CylinderGeometry(5, 5, 3, 30, 30));
var ball = new THREE.Mesh(sphereGeometry, sphereMaterial)
+
cylinder2.position.x = 10;
 
+
cylinder2.rotation.x = -0.5*Math.PI;
scene.add(ball);
+
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 sphereGeometry = new THREE.SphereGeometry(0.5,20,20);
+
//Перемычка
var sphereMaterial = new THREE.MeshLambertMaterial({color:0x777700, wireframe:true});
+
var cylinder6 = createMesh(new THREE.CylinderGeometry(0.3, 0.3, 3, 30, 30));
var ball1 = new THREE.Mesh(sphereGeometry, sphereMaterial)
+
cylinder6.position.z = -1.5;
 
+
cylinder6.rotation.x = -0.5*Math.PI;
scene.add(ball1);
 
var radius = 5;
 
var segments = 32;
 
 
 
var line_geometry = new THREE.Geometry();
+
//Вектора скоростей
    line_geometry.vertices.push(new THREE.Vector3(0,5,0));
+
        var vectorMaterial = new THREE.MeshLambertMaterial({color: 0x00ee22});
    line_geometry.vertices.push(new THREE.Vector3(20,5,0));
 
var   material_line = new THREE.LineBasicMaterial({ color: 0x6699FF, linewidth: 5000, fog:false});
 
var line = new THREE.Line(line_geometry,material_line);
 
  
        scene.add( line );
+
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 spotLight = new THREE.SpotLight(0xffffff);
+
var vector2lineGeometry = new THREE.CylinderGeometry(0.1, 0.1, 5, 30, 30);
        spotLight.position.set(10,30,30)     
+
var vector2line = new THREE.Mesh(vector2lineGeometry, vectorMaterial);
        scene.add(spotLight);
+
vector2line.position.x = 10;
var spotLight1 = new THREE.SpotLight(0xffffff);
+
vector2line.position.y = 2.5;
        spotLight.position.set(10,10,0)
+
vector2line.position.z = 1.5;
        scene.add(spotLight1);
 
 
 
render.shadowMapEnabled = true;
+
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;
 
 
cylinder.castShadow = true;
+
//Группа подвижных объектов
cylinder1.castShadow = true;
+
var group1 = new THREE.Object3D();
cylinder2.castShadow = true;
+
group1.add(cylinder2);
spotLight.castShadow = true;
+
group1.add(cylinder3);
    spotLight1.castShadow = true;
+
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= 0;
+
var mesh = new THREE.Mesh(geom, mat);
camera.position.y= 80;
+
camera.position.z= 0;
+
return mesh;
camera.lookAt(scene.position);
+
        }
$("#webGL").append(render.domElement);
+
 +
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.rotationSpeed = 0.01;
+
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)
 
 
this.Radius = 5;
+
vector1line.scale.set(1, e, 1)
}
+
vector1.scale.set(1, e, 1)
var gui = new dat.GUI();
+
vector1line.position.set(e*20, e*5, 1.5)
gui.add(controls, 'rotationSpeed',0,0.5);
+
vector1.position.set(e*20, e*10, 1.5)
+
   
+
vector2line.scale.set(1, e, 1)
gui.add(controls,'Radius',1,15);
+
vector2.scale.set(1, e, 1)
 
+
vector2line.position.set(e*10, e*2.5, 1.5)
    control1 = new THREE.OrbitControls(camera);
+
vector2.position.set(e*10, e*5, 1.5)
    control1.dumping = 0.2;
+
});
 
+
gui.add(controls, 'Boost').listen();
var trajectoryGeometry = new THREE.SphereGeometry(0.05, 2, 2);
+
gui.add(controls, 'Stop');
var trajectoryMaterial = new THREE.MeshBasicMaterial( {color: 0x000000,wireframe:true} );
+
gui.add(controls, 'Redraw');
var trajectory1Geometry = new THREE.SphereGeometry(0.05, 2, 2);
 
var trajectory1Material = new THREE.MeshBasicMaterial( {color: 0x0000ff,wireframe:true} );
 
 
 
 
 
var step = 0;
 
var step = 0;
 
 
+
function render() {
+
stats.update();
+
requestAnimationFrame(render);
+
webGLRenderer.render(scene, camera);
renderer();
+
if (step<50){
function renderer()
+
step += 0.01;
{
+
+
controls.Boost = controls.Moment/(22*controls.Massa*controls.Radius*controls.Radius);
 
 
var r=10-controls.Radius;
 
    var k = r/controls.Radius;
 
 
var r1=20-controls.Radius;
 
    var k1 = r1/controls.Radius;
 
 
cylinder.position.x=10*(Math.cos(step));
 
cylinder.position.z=10*(Math.sin(step));
 
cube.position.x=10*(Math.cos(step));
 
cube.position.z=10*(Math.sin(step));
 
cylinder2.position.x=20*(Math.cos(step));
 
cylinder2.position.z=20*(Math.sin(step));
 
step+=controls.rotationSpeed*0.3;
 
 
 
 
cylinder.rotation.y-=controls.rotationSpeed;
 
cylinder2.rotation.y+=controls.rotationSpeed;
 
cube.rotation.y-=controls.rotationSpeed*0.3;
 
line.rotation.y-=controls.rotationSpeed*0.3;
 
requestAnimationFrame(renderer);
 
control1.update();
 
 
cylinder.scale.set(controls.Radius,1,controls.Radius);
 
cylinder1.scale.set(10-controls.Radius,1,10-controls.Radius);
 
cylinder2.scale.set(10-controls.Radius,1,10-controls.Radius);
 
 
 
ball.position.x = controls.Radius*(k+1)*(Math.cos(step)-(Math.cos((k+1)*step))/(k+1));
+
cylinder2.rotation.y -= 1/4*controls.Boost*step*step;
ball.position.y = 5;
+
cylinder3.rotation.y += 1/4*controls.Boost*step*step;
ball.position.z = controls.Radius*(k+1)*(Math.sin(step)-(Math.sin((k+1)*step))/(k+1));
+
group1.rotation.z += 1/4*controls.Boost*step*step;
 
+
}
ball1.position.x = controls.Radius*(k1+1)*(Math.cos(step)+(Math.cos((k1+1)*step))/(k1+1));
+
else {
ball1.position.y = 5;
+
step = 50
ball1.position.z = controls.Radius*(k1+1)*(Math.sin(step)-(Math.sin((k1+1)*step))/(k1+1));
+
var trajectory = new THREE.Mesh(trajectoryGeometry, trajectoryMaterial);
+
controls.Boost = controls.Moment/(22*controls.Massa*controls.Radius*controls.Radius);
trajectory.position.x = ball.position.x;
 
trajectory.position.y = 5;
 
trajectory.position.z = ball.position.z;
 
 
scene.add( trajectory );
 
 
 
var trajectory1 = new THREE.Mesh(trajectoryGeometry, trajectoryMaterial);
+
cylinder2.rotation.y -= 1/4*controls.Boost*step*step;
trajectory1.position.x = ball1.position.x;
+
cylinder3.rotation.y += 1/4*controls.Boost*step*step;
trajectory1.position.y = 5;
+
group1.rotation.z += 1/4*controls.Boost*step*step;
trajectory1.position.z = ball1.position.z;
+
}
 
scene.add( trajectory1 );
 
render.render(scene,camera);
 
this.submit = renderer;
 
 
 
}
 
}
this.start = renderer;
 
  this.stopName=stopIt;
 
  function stopIt()
 
  {
 
    controls.rotationSpeed = 0;
 
    stop = controls.rotationSpeed;
 
  }
 
 
this.addOrbit = function(pos, radius)
 
{
 
    //Задаем размер сегмента.
 
    var resolution = 170;
 
    var size = 360 / resolution;
 
    //Геометрия и материал
 
    var geometry = new THREE.Geometry();
 
    var material = new THREE.LineBasicMaterial( { color: 0xff0000} );
 
    for(var i = 0; i <= resolution; i++) {
 
        //Вычисляем угол сегмента, т.е. наш размер * смещение * 1 радиан.
 
        var segment = ( i * size ) * Math.PI / 180;
 
        //Вычисляем кординаты как косинус\синус угла нашего сегмента, что есть координата х\y для единичного радиуса, и умножаем на радиус, т.е. отдаляем координату.
 
        geometry.vertices.push( new THREE.Vertex( new THREE.Vector3( Math.cos( segment ) * radius, Math.sin( segment ) * radius ), 0 ) );       
 
    }
 
    //Создаем линию и устанавливаем её позицию
 
    var line = new THREE.Line( geometry, material );
 
    line.position.x = pos.x;
 
    line.position.y = pos.y;
 
    this.scene.add(line);
 
 
    return line;
 
 
}
 
 
 
 +
        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
+
* OrbitControls.js
* stats.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

Уравнения

Если центр неподвижной окружности находится в начале координат, её радиус равен [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]