Текущая версия |
Ваш текст |
Строка 1: |
Строка 1: |
| '''''Задача:''''' С помощью языка программирования JavaScript смоделировать планетарный механизм. | | '''''Задача:''''' С помощью языка программирования JavaScript смоделировать планетарный механизм. |
− | [[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>
| |