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

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Код программы)
Строка 9: Строка 9:
 
==Код программы==
 
==Код программы==
 
<div class="mw-collapsible mw-collapsed">
 
<div class="mw-collapsible mw-collapsed">
'''Текст программы на языке JavaScript:'''
+
'''Текст программы на языке JavaScript:''' <div class="mw-collapsible-content">
<div id="WebGL-output">
+
<syntaxhighlight lang="javascript" line start="1" enclose="div">
</div>
+
var renderer, scene, camera, stats, axes;
<div id="Stats-output">
+
  var control, controls, controls1, spotLight;
</div>
+
  var plane1, plane2, plane3, block1, block2, torus, cube, arr1, arr2, arr3, arr4, cr1,cr2,cr3;
<!--Javascript code that runs our Three.js examples -->
+
  var dt = 1/60;
<script type="text/javascript">
+
  var g = 9.8;
// once everything is loaded, we run our Three.js stuff.
+
  var length = 30;
$(function () {
+
  var cubeY = 25;
var dt = 1/60;
+
  /////    ЗАДАНИЕ ПАРАМЕТРОВ, УКАЗАННЫХ В ЗАДАЧЕ    /////
var g = 9.8;
 
function ksi(t) {
 
return 0.125*t*t;
 
}
 
function dksi(t) {
 
return (ksi(t+0.001)-ksi(t))/0.001;
 
}
 
function ddksi(t) {
 
return (dksi(t+0.001)-dksi(t))/0.001;
 
}
 
var c = new function() {
 
this.animate=false;
 
this.alpha=Math.PI/6;
 
this.m=1;
 
this.l=4;
 
this.t=0;
 
this.fi = 0;
 
<!-- this.eps=-g/this.l*Math.sin(this.fi)-2/this.l*Math.cos(this.fi-this.alpha); -->
 
<!-- this.omega=this.eps*this.t; -->
 
<!-- this.ksi=0.125*this.t*this.t; -->
 
this.calculate = function() {
 
if(this.t>Math.sqrt(40*8)) {this.t=0};
 
this.dksi = dksi(this.t);
 
this.ddksi = ddksi(this.t);
 
this.ksi=ksi(this.t);
 
this.eps=-g/this.l*Math.sin(this.fi)-this.ddksi/this.l*Math.cos(this.fi-this.alpha);
 
this.omega=this.eps*this.t;
 
this.fi=Math.PI/6*Math.sin(Math.sqrt(g/this.l)*this.t+Math.PI/6);//this.eps*this.t*this.t/2;
 
}
 
this.calculate();
 
this.setDefault = function() {
 
this.t = 0;
 
this.calculate();
 
}
 
}
 
console.log(c);
 
var gui = new dat.GUI();
 
var animeChange = gui.add(c,'animate');
 
var alphaChange = gui.add(c,'alpha',0,Math.PI/3);
 
gui.add(c,'ksi').listen();
 
gui.add(c,'t').listen();
 
gui.add(c,'fi').listen();
 
gui.add(c,'omega').listen();
 
gui.add(c,'eps').listen();
 
 
 
animeChange.onFinishChange(function(value) {
 
c.setDefault();
 
c.calculate();
 
});
 
alphaChange.onFinishChange(function(value) {
 
c.setDefault();
 
c.calculate();
 
});
 
 
 
var scene = new THREE.Scene();
 
 
/*
 
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight , 0.1, 1000);
 
camera.position.x = 10;
 
camera.position.y = 10;
 
camera.position.z = 50;
 
*/
 
//*z
 
var camera = new THREE.OrthographicCamera( window.innerWidth / - 50, window.innerWidth / 50, window.innerHeight / 50, window.innerHeight / - 50, 1, 100 );
 
camera.position.x = 0;
 
camera.position.y = 0;
 
camera.position.z = 30;
 
//*/
 
var renderer = new THREE.WebGLRenderer();
 
renderer.setClearColor(0xe2f1fd);
 
renderer.setSize(window.innerWidth, window.innerHeight);
 
while(scene.children.length > 0){
 
scene.remove(scene.children[0]);
 
}
 
var axes = new THREE.AxesHelper( 20 );
 
scene.add(axes);
 
 
control = new THREE.OrbitControls(camera,renderer.domElement);
 
 
// ��������� ������
 
<!-- function Curve1() { -->
 
    <!-- THREE.Curve.call(this); -->
 
    <!-- }; -->
 
    <!-- Curve1.prototype = Object.create(THREE.Curve.prototype); -->
 
    <!-- Curve1.prototype.constructor = Curve1; -->
 
    <!-- Curve1.prototype.getPoint = function(t) { -->
 
    <!-- var tx = t*c.ksi*Math.cos(c.alpha); -->
 
    <!-- var ty = t*c.ksi*Math.sin(c.alpha); -->
 
    <!-- return new THREE.Vector3(tx,ty,0); -->
 
    <!-- }; -->
 
    <!-- var path1 = new Curve1(); -->
 
    <!-- scene.add(new THREE.Mesh(new THREE.TubeGeometry(path1,15,0.2,3), new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true}))); -->
 
var h = 40
 
var cyl = new THREE.Mesh(new THREE.CylinderGeometry(0.2,0.2,h,32,5,0), new THREE.MeshLambertMaterial({color: 0xEEEEEE, wireframe:false}));
 
scene.add(cyl);
 
 
// ������
 
var pod = new THREE.Mesh(new THREE.SphereGeometry(0.4,8,8), new THREE.MeshLambertMaterial({color: 0xff0000, wireframe:false}));
 
scene.add(pod);
 
 
var tab = new THREE.Mesh(new THREE.CylinderGeometry(0.2,0.2,c.l,32,5,0), new THREE.MeshLambertMaterial({color: 0xEEEEEE, wireframe:false}));
 
tab.rotation.set(0,0,c.fi);
 
tab.position.set(pod.position.x+c.l/2*Math.sin(c.fi),pod.position.y-c.l/2*Math.cos(c.fi),0);
 
scene.add(tab);
 
 
  
var w = new THREE.Mesh(new THREE.SphereGeometry(0.8,8,8), new THREE.MeshLambertMaterial({color: 0x00ff00, wireframe:false}));
+
  function init()
scene.add(w);
+
  {
+
    scene = new THREE.Scene();  // создаем сцену
 +
    camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000); // создаем камеру
  
var spotLight = new THREE.SpotLight( 0xffffff );
+
    renderer = new THREE.WebGLRenderer();
spotLight.position.set( 0, 80, 30 );
+
    renderer.setClearColor(0XEEEEEE,1);
spotLight.castShadow = true;
+
    renderer.setSize(window.innerWidth,window.innerHeight);
scene.add(spotLight );
+
    renderer.shadowMap.enabled=true;
//camera.lookAt(scene.position);
+
 
+
    axes = new THREE.AxisHelper(20);  // создаем координатные оси
function initStats()
+
    scene.add(axes);
{
+
 
var stats=new Stats();
+
 
stats.setMode(0);
+
 
stats.domElement.style.position='0px';
+
    control = new THREE.OrbitControls(camera,renderer.domElement);
stats.domElement.style.left='0px';
+
 
stats.domElement.style.top='0px';
+
    controls = new function()  // создаем переключатели, позволяющие изменять входные параметры
document.getElementById("Stats-output").appendChild(stats.domElement);
+
    {
return stats;
+
      this.alpha = Math.PI/6;
};
+
      this.blockRadius = 3;
 +
      this.m1 = 3;
 +
      this.m2 = 1;
 +
      this.animate = false;
 +
      this.showAcs = false;
 +
      this.reset  = function() {
 +
        controls1.t = 0;
 +
        ReDraw();
 +
      }
 +
    }
 +
 
 +
    controls1=new function()  // вывод полученных в ходе решения задачи значений
 +
    {
 +
      this.t = 0.0;
 +
      this.a = (controls.m1*g*Math.sin(controls.alpha)-controls.m2*g)/(2*controls.m1+controls.m2);
 +
    }
 +
 
 +
    var gui = new dat.GUI();  // позволяем менять каждый из параметров в определенном диапазоне, в случае изменения вызываем функцию, перестраивающую выводимую на экран картинку
 +
    gui.add(controls,'alpha', 0.1,Math.PI/3).onChange(controls.reset);
 +
    gui.add(controls,'m1',1,20).onChange(controls.reset);
 +
    gui.add(controls,'m2',1,20).onChange(controls.reset);
 +
    gui.add(controls, 'animate');
 +
    gui.add(controls, 'showAcs').onChange(ReDraw);
 +
    gui.add(controls, 'reset');
 +
    //gui.add(controls,'m',1,10).onChange(ReDraw);
 +
    gui.add(controls1, 't').listen();
 +
    gui.add(controls1, 'a').listen();
 +
 
 +
    ambientLight=new THREE.AmbientLight(0x000000);
 +
    scene.add(ambientLight);
 +
    document.getElementById("WebGL").appendChild(renderer.domElement);
 +
    // Camera
 +
    camera.position.x = -30;
 +
    camera.position.y = 40;
 +
    camera.position.z = 80;
 +
    camera.lookAt(scene.position);
 +
    // Ligth
 +
    spotLight = new THREE.SpotLight( 0xffffff );
 +
    spotLight.position.set( -40, 80, 50 );
 +
    spotLight.castShadow = true;
 +
    scene.add(spotLight );
 +
 
 +
    // Main Plane
 +
    var planeGeometry2 = new THREE.PlaneGeometry(length,20);
 +
    var planeMaterial2 = new THREE.MeshLambertMaterial({color: 0x6F482A, side: THREE.DoubleSide});
 +
    plane1 = new THREE.Mesh(planeGeometry2,planeMaterial2);
 +
    plane1.rotation.x = -0.5*Math.PI;
 +
    plane1.position.x = -length/2;
 +
    plane1.position.y = 0;
 +
    plane1.position.z = 0;
 +
    plane1.receiveShadow = true;
 +
    scene.add(plane1);
 +
 
 +
    // Third Plane
 +
    var planeGeometry2 = new THREE.PlaneGeometry(length,20,6,4);
 +
    var planeMaterial2 = new THREE.MeshLambertMaterial({color: 0x6F482A, wireframe: true});
 +
    plane2 = new THREE.Mesh(planeGeometry2,planeMaterial2);
 +
    plane2.rotation.x = -0.5*Math.PI;
 +
    plane2.position.set(length/2,0,0);
 +
    scene.add(plane2);
 +
 
 +
    stats = initStats();
 +
    Draw();
 +
    renderScene();
 +
 
 +
    window.addEventListener('resize',onResize,false);
 +
  };
 +
 
 +
  function ReDraw()  // функция, перерисовывающая всю картинку
 +
  {
 +
    controls1.a = (controls.m1*g*Math.sin(controls.alpha)-controls.m2*g)/(2*controls.m1+controls.m2);
 +
    scene.remove(block1);
 +
    scene.remove(block2);
 +
    scene.remove(cube);
 +
    scene.remove(plane3);
 +
    scene.remove(torus);
 +
    scene.remove(cr1);
 +
    scene.remove(cr2);
 +
    scene.remove(cr3);
 +
    scene.remove(arr1);
 +
    scene.remove(arr2);
 +
    scene.remove(arr3);
 +
    scene.remove(arr4);
 +
    Draw();
 +
  }
 +
 
 +
  function Draw()
 +
  {
 +
 
 +
    // Second Plane
 +
    var planeGeometry3 = new THREE.PlaneGeometry(length/Math.cos(controls.alpha),20);
 +
    var planeMaterial3 = new THREE.MeshLambertMaterial({color: 0x6F482A, wireframe: false, side: THREE.DoubleSide});
 +
    plane3 = new THREE.Mesh(planeGeometry3,planeMaterial3);
 +
    plane3.rotation.set(-0.5*Math.PI,-controls.alpha,0);
 +
    plane3.position.set(length/2,0.5*length*Math.tan(controls.alpha),0);
 +
    plane3.receiveShadow = true;
 +
    scene.add(plane3);
 +
    // Block1
 +
    block1 = new THREE.Mesh(new THREE.CylinderGeometry(controls.blockRadius,controls.blockRadius,3,32), new THREE.MeshLambertMaterial({color: 0xA8A8A8, wireframe: false, side: THREE.DoubleSide}));
 +
    block1.rotation.set(-0.5*Math.PI,0,0);
 +
    block1.position.set(length,length*Math.tan(controls.alpha),0);
 +
    block1.castShadow = true;
 +
    scene.add(block1);
 +
    // Block2
 +
    block2 = new THREE.Mesh(new THREE.CylinderGeometry(controls.blockRadius,controls.blockRadius,3,32), new THREE.MeshLambertMaterial({color: 0xA8A8A8, wireframe: false, side: THREE.DoubleSide}));
 +
    block2.rotation.set(-0.5*Math.PI,0,0);
 +
    block2.position.x = length/2-controls1.a*controls1.t*controls1.t*Math.cos(controls.alpha)*0.5;
 +
    block2.position.y = block2.position.x*Math.tan(controls.alpha)+controls.blockRadius/Math.cos(controls.alpha);
 +
    block2.castShadow = true;
 +
    scene.add(block2);
 +
    // Thorus
 +
    torus = new THREE.Mesh( new THREE.TorusGeometry( 6, 0.1, 16, 100, controls.alpha ), new THREE.MeshBasicMaterial( { color: 0xff0000 } ) );
 +
    torus.position.set(0,0,9.9)
 +
    scene.add(torus);
 +
    // Cube
 +
    cube = new THREE.Mesh(new THREE.BoxGeometry(4, 4, 4), new THREE.MeshLambertMaterial({color: 0x7CA05A, wireframe: false}));
 +
    cube.position.set(length+controls.blockRadius,-cubeY+controls1.a*controls1.t*controls1.t,0);
 +
    scene.add(cube);
 +
    //More rope
 +
    cr1 = new THREE.Mesh(new THREE.CylinderGeometry(0.2,0.2,(length*Math.tan(controls.alpha)+cubeY),32), new THREE.MeshLambertMaterial({color: 0x000000, wireframe: false}));
 +
    cr1.rotation.set(0,0,0);
 +
    cr1.position.set(length+controls.blockRadius, (length*Math.tan(controls.alpha)+cube.position.y)/2, 0);
 +
    cr1.scale.y = (length*Math.tan(controls.alpha)-cube.position.y)/(length*Math.tan(controls.alpha)+cubeY);
 +
    cr1.castShadow = true;
 +
    scene.add(cr1);
 +
 
 +
    cr2 = new THREE.Mesh(new THREE.CylinderGeometry(0.2,0.2,1), new THREE.MeshLambertMaterial({color: 0x000000, wireframe: false}));
 +
    cr2.rotation.set(0,0,-Math.PI/2+controls.alpha);
 +
    cr2.position.set((length+block2.position.x-controls.blockRadius*Math.sin(controls.alpha))/2,(length*Math.tan(controls.alpha)+block2.position.y+controls.blockRadius*Math.cos(controls.alpha))/2, 0);
 +
    cr2.scale.y = (length-block2.position.x-controls.blockRadius*Math.sin(controls.alpha))/Math.cos(controls.alpha);
 +
    cr2.castShadow = true;
 +
    scene.add(cr2);
 +
 
 +
    function Curve2() {
 +
      THREE.Curve.call(this);
 +
    };
 +
    Curve2.prototype = Object.create(THREE.Curve.prototype);
 +
    Curve2.prototype.constructor = Curve2;
 +
    Curve2.prototype.getPoint = function(t) {
 +
      var tx = length+controls.blockRadius*Math.cos(controls.alpha+Math.PI*0.5-t*(controls.alpha+Math.PI*0.5));
 +
      var ty = length*Math.tan(controls.alpha)+controls.blockRadius*Math.sin(controls.alpha+Math.PI*0.5-t*(controls.alpha+Math.PI*0.5));
 +
      return new THREE.Vector3(tx,ty,0);
 +
    };
 +
    var path2 = new Curve2();
 +
    cr3 = new THREE.Mesh(new THREE.TubeGeometry(path2,20,0.2,8), new THREE.MeshBasicMaterial({color: 0x000000, wireframe: false}));
 +
    scene.add(cr3);
 +
 
 +
    //arrows
 +
    arr1 = new THREE.Mesh(new THREE.CylinderGeometry(0.3,0.3,4,32), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
 +
    arr1.rotation.set(0,0,0);
 +
    arr1.position.set(length+controls.blockRadius,cube.position.y+controls.m2*2+controls1.a*2,0);
 +
    arr1.scale.y = controls1.a;
 +
    if (!controls.showAcs) {arr1.visible = false}
 +
    else {arr1.visible = true}
 +
    scene.add(arr1);
 +
    arr2 = new THREE.Mesh(new THREE.CylinderGeometry(0,0.7,Math.sign(controls1.a)*2,32), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
 +
    arr2.rotation.set(0,0,0);
 +
    arr2.position.set(length+controls.blockRadius,cube.position.y+controls.m2*2+controls1.a*4,0);
 +
    if (!controls.showAcs) {arr2.visible = false}
 +
    else {arr2.visible = true}
 +
    scene.add(arr2);
 +
    arr3 = new THREE.Mesh(new THREE.CylinderGeometry(0.3,0.3,4,32), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true}));
 +
    arr3.rotation.set(0,0,-1.5*Math.PI+controls.alpha);
 +
    arr3.position.set(block2.position.x-Math.sign(controls1.a)*(controls.blockRadius)*Math.cos(controls.alpha)-controls1.a*2*Math.cos(controls.alpha),block2.position.y-Math.sign(controls1.a)*(controls.blockRadius)*Math.sin(controls.alpha)-controls1.a*2*Math.sin(controls.alpha),0);
 +
    arr3.scale.y = controls1.a;
 +
    if (!controls.showAcs) {arr3.visible = false}
 +
    else {arr3.visible = true}
 +
    scene.add(arr3);
 +
    arr4 = new THREE.Mesh(new THREE.CylinderGeometry(0,0.7,-Math.sign(controls1.a)*2,32), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
 +
    arr4.rotation.set(0,0,-Math.PI/2+controls.alpha);
 +
    arr4.position.set(block2.position.x-Math.sign(controls1.a)*(controls.blockRadius)*Math.cos(controls.alpha)-controls1.a*4*Math.cos(controls.alpha),block2.position.y-Math.sign(controls1.a)*(controls.blockRadius)*Math.sin(controls.alpha)-controls1.a*4*Math.sin(controls.alpha),0);
 +
    if (!controls.showAcs) {arr4.visible = false}
 +
    else {arr4.visible = true}
 +
    scene.add(arr4);
 +
 
 +
    renderer.render(scene,camera);
 +
  }
 +
 
 +
  function renderScene()
 +
  {
 +
    if((block2.position.y <= controls.blockRadius) || (cube.position.y >= length*Math.tan(controls.alpha)-controls.blockRadius) || (((block2.position.y-block1.position.y)*(block2.position.y-block1.position.y)+(block2.position.x-block1.position.x)*(block2.position.x-block1.position.x)) <= 4*controls.blockRadius*controls.blockRadius)) {
 +
      controls1.t = 0;
 +
    }
 +
    if (controls.animate)
 +
    {
 +
      controls1.t+=dt;
 +
      ReDraw();
 +
    }
 +
 
 +
    stats.update();
 +
    requestAnimationFrame(renderScene);
 +
    renderer.render(scene,camera);
 +
  };
 +
 
 +
  function initStats()
 +
  {
 +
    var stats=new Stats();
 +
    stats.setMode(0);
 +
    stats.domElement.style.position='0px';
 +
    stats.domElement.style.left='0px';
 +
    stats.domElement.style.top='0px';
 +
    document.getElementById("Stats-output").appendChild(stats.domElement);
 +
    return stats;
 +
  };
 +
 
 +
  function onResize()
 +
  {
 +
    camera.aspect=window.innerWidth/window.innerHeight;
 +
    camera.updateProjectionMatrix();
 +
    renderer.setSize(window.innerWidth,window.innerHeight);
 +
  }
 +
 
 +
  window.onload = init;
 +
</syntaxhighlight>
  
stats = initStats();
 
 
function renderScene() {
 
stats.update();
 
if(c.animate) {c.t+=dt;}
 
c.calculate();
 
cyl.rotation.set(0,0,-Math.PI/2+c.alpha);
 
cyl.position.set(h/2*Math.cos(c.alpha),h/2*Math.sin(c.alpha),0);
 
pod.position.set(c.ksi*Math.cos(c.alpha),c.ksi*Math.sin(c.alpha),0);
 
tab.rotation.set(0,0,c.fi);
 
tab.position.set(pod.position.x+c.l/2*Math.sin(c.fi),pod.position.y-c.l/2*Math.cos(c.fi),0);
 
w.position.set(pod.position.x+c.l*Math.sin(c.fi),pod.position.y-c.l*Math.cos(c.fi),0);
 
requestAnimationFrame(renderScene);
 
renderer.render(scene, camera);
 
}
 
go = function() {
 
$("#WebGL-output").append(renderer.domElement);
 
    renderScene();
 
};
 
go();
 
});
 
</script>
 
 
</div>
 
</div>
 
  
 
== Возможности программы ==
 
== Возможности программы ==

Версия 11:36, 22 декабря 2017

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

Выполнил: Троцкая Валерия, 23632/2

Решение

Код программы

Текст программы на языке JavaScript:
  1 var renderer, scene, camera, stats, axes;
  2   var control, controls, controls1, spotLight;
  3   var plane1, plane2, plane3, block1, block2, torus, cube, arr1, arr2, arr3, arr4, cr1,cr2,cr3;
  4   var dt = 1/60;
  5   var g = 9.8;
  6   var length = 30;
  7   var cubeY = 25;
  8   /////    ЗАДАНИЕ ПАРАМЕТРОВ, УКАЗАННЫХ В ЗАДАЧЕ    /////
  9 
 10   function init()
 11   {
 12     scene = new THREE.Scene();  // создаем сцену
 13     camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);  // создаем камеру
 14 
 15     renderer = new THREE.WebGLRenderer();
 16     renderer.setClearColor(0XEEEEEE,1);
 17     renderer.setSize(window.innerWidth,window.innerHeight);
 18     renderer.shadowMap.enabled=true;
 19 
 20     axes = new THREE.AxisHelper(20);  // создаем координатные оси
 21     scene.add(axes);
 22 
 23 
 24 
 25     control = new THREE.OrbitControls(camera,renderer.domElement);
 26 
 27     controls = new function()  // создаем переключатели, позволяющие изменять входные параметры
 28     {
 29       this.alpha = Math.PI/6;
 30       this.blockRadius = 3;
 31       this.m1 = 3;
 32       this.m2 = 1;
 33       this.animate = false;
 34       this.showAcs = false;
 35       this.reset  = function() {
 36         controls1.t = 0;
 37         ReDraw();
 38       }
 39     }
 40 
 41     controls1=new function()   // вывод полученных в ходе решения задачи значений
 42     {
 43       this.t = 0.0;
 44       this.a = (controls.m1*g*Math.sin(controls.alpha)-controls.m2*g)/(2*controls.m1+controls.m2);
 45     }
 46 
 47     var gui = new dat.GUI();  // позволяем менять каждый из параметров в определенном диапазоне, в случае изменения вызываем функцию, перестраивающую выводимую на экран картинку
 48     gui.add(controls,'alpha', 0.1,Math.PI/3).onChange(controls.reset);
 49     gui.add(controls,'m1',1,20).onChange(controls.reset);
 50     gui.add(controls,'m2',1,20).onChange(controls.reset);
 51     gui.add(controls, 'animate');
 52     gui.add(controls, 'showAcs').onChange(ReDraw);
 53     gui.add(controls, 'reset');
 54     //gui.add(controls,'m',1,10).onChange(ReDraw);
 55     gui.add(controls1, 't').listen();
 56     gui.add(controls1, 'a').listen();
 57 
 58     ambientLight=new THREE.AmbientLight(0x000000);
 59     scene.add(ambientLight);
 60     document.getElementById("WebGL").appendChild(renderer.domElement);
 61     // Camera
 62     camera.position.x = -30;
 63     camera.position.y = 40;
 64     camera.position.z = 80;
 65     camera.lookAt(scene.position);
 66     // Ligth
 67     spotLight = new THREE.SpotLight( 0xffffff );
 68     spotLight.position.set( -40, 80, 50 );
 69     spotLight.castShadow = true;
 70     scene.add(spotLight );
 71 
 72     // Main Plane
 73     var planeGeometry2 = new THREE.PlaneGeometry(length,20);
 74     var planeMaterial2 = new THREE.MeshLambertMaterial({color: 0x6F482A, side: THREE.DoubleSide});
 75     plane1 = new THREE.Mesh(planeGeometry2,planeMaterial2);
 76     plane1.rotation.x = -0.5*Math.PI;
 77     plane1.position.x = -length/2;
 78     plane1.position.y = 0;
 79     plane1.position.z = 0;
 80     plane1.receiveShadow = true;
 81     scene.add(plane1);
 82 
 83     // Third Plane
 84     var planeGeometry2 = new THREE.PlaneGeometry(length,20,6,4);
 85     var planeMaterial2 = new THREE.MeshLambertMaterial({color: 0x6F482A, wireframe: true});
 86     plane2 = new THREE.Mesh(planeGeometry2,planeMaterial2);
 87     plane2.rotation.x = -0.5*Math.PI;
 88     plane2.position.set(length/2,0,0);
 89     scene.add(plane2);
 90 
 91     stats = initStats();
 92     Draw();
 93     renderScene();
 94 
 95     window.addEventListener('resize',onResize,false);
 96   };
 97 
 98   function ReDraw()  // функция, перерисовывающая всю картинку
 99   {
100     controls1.a = (controls.m1*g*Math.sin(controls.alpha)-controls.m2*g)/(2*controls.m1+controls.m2);
101     scene.remove(block1);
102     scene.remove(block2);
103     scene.remove(cube);
104     scene.remove(plane3);
105     scene.remove(torus);
106     scene.remove(cr1);
107     scene.remove(cr2);
108     scene.remove(cr3);
109     scene.remove(arr1);
110     scene.remove(arr2);
111     scene.remove(arr3);
112     scene.remove(arr4);
113     Draw();
114   }
115 
116   function Draw()
117   {
118 
119     // Second Plane
120     var planeGeometry3 = new THREE.PlaneGeometry(length/Math.cos(controls.alpha),20);
121     var planeMaterial3 = new THREE.MeshLambertMaterial({color: 0x6F482A, wireframe: false, side: THREE.DoubleSide});
122     plane3 = new THREE.Mesh(planeGeometry3,planeMaterial3);
123     plane3.rotation.set(-0.5*Math.PI,-controls.alpha,0);
124     plane3.position.set(length/2,0.5*length*Math.tan(controls.alpha),0);
125     plane3.receiveShadow = true;
126     scene.add(plane3);
127     // Block1
128     block1 = new THREE.Mesh(new THREE.CylinderGeometry(controls.blockRadius,controls.blockRadius,3,32), new THREE.MeshLambertMaterial({color: 0xA8A8A8, wireframe: false, side: THREE.DoubleSide}));
129     block1.rotation.set(-0.5*Math.PI,0,0);
130     block1.position.set(length,length*Math.tan(controls.alpha),0);
131     block1.castShadow = true;
132     scene.add(block1);
133     // Block2
134     block2 = new THREE.Mesh(new THREE.CylinderGeometry(controls.blockRadius,controls.blockRadius,3,32), new THREE.MeshLambertMaterial({color: 0xA8A8A8, wireframe: false, side: THREE.DoubleSide}));
135     block2.rotation.set(-0.5*Math.PI,0,0);
136     block2.position.x = length/2-controls1.a*controls1.t*controls1.t*Math.cos(controls.alpha)*0.5;
137     block2.position.y = block2.position.x*Math.tan(controls.alpha)+controls.blockRadius/Math.cos(controls.alpha);
138     block2.castShadow = true;
139     scene.add(block2);
140     // Thorus
141     torus = new THREE.Mesh( new THREE.TorusGeometry( 6, 0.1, 16, 100, controls.alpha ), new THREE.MeshBasicMaterial( { color: 0xff0000 } ) );
142     torus.position.set(0,0,9.9)
143     scene.add(torus);
144     // Cube
145     cube = new THREE.Mesh(new THREE.BoxGeometry(4, 4, 4), new THREE.MeshLambertMaterial({color: 0x7CA05A, wireframe: false}));
146     cube.position.set(length+controls.blockRadius,-cubeY+controls1.a*controls1.t*controls1.t,0);
147     scene.add(cube);
148     //More rope
149     cr1 = new THREE.Mesh(new THREE.CylinderGeometry(0.2,0.2,(length*Math.tan(controls.alpha)+cubeY),32), new THREE.MeshLambertMaterial({color: 0x000000, wireframe: false}));
150     cr1.rotation.set(0,0,0);
151     cr1.position.set(length+controls.blockRadius, (length*Math.tan(controls.alpha)+cube.position.y)/2, 0);
152     cr1.scale.y = (length*Math.tan(controls.alpha)-cube.position.y)/(length*Math.tan(controls.alpha)+cubeY);
153     cr1.castShadow = true;
154     scene.add(cr1);
155 
156     cr2 = new THREE.Mesh(new THREE.CylinderGeometry(0.2,0.2,1), new THREE.MeshLambertMaterial({color: 0x000000, wireframe: false}));
157     cr2.rotation.set(0,0,-Math.PI/2+controls.alpha);
158     cr2.position.set((length+block2.position.x-controls.blockRadius*Math.sin(controls.alpha))/2,(length*Math.tan(controls.alpha)+block2.position.y+controls.blockRadius*Math.cos(controls.alpha))/2, 0);
159     cr2.scale.y = (length-block2.position.x-controls.blockRadius*Math.sin(controls.alpha))/Math.cos(controls.alpha);
160     cr2.castShadow = true;
161     scene.add(cr2);
162 
163     function Curve2() {
164       THREE.Curve.call(this);
165     };
166     Curve2.prototype = Object.create(THREE.Curve.prototype);
167     Curve2.prototype.constructor = Curve2;
168     Curve2.prototype.getPoint = function(t) {
169       var tx = length+controls.blockRadius*Math.cos(controls.alpha+Math.PI*0.5-t*(controls.alpha+Math.PI*0.5));
170       var ty = length*Math.tan(controls.alpha)+controls.blockRadius*Math.sin(controls.alpha+Math.PI*0.5-t*(controls.alpha+Math.PI*0.5));
171       return new THREE.Vector3(tx,ty,0);
172     };
173     var path2 = new Curve2();
174     cr3 = new THREE.Mesh(new THREE.TubeGeometry(path2,20,0.2,8), new THREE.MeshBasicMaterial({color: 0x000000, wireframe: false}));
175     scene.add(cr3);
176 
177     //arrows
178     arr1 = new THREE.Mesh(new THREE.CylinderGeometry(0.3,0.3,4,32), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
179     arr1.rotation.set(0,0,0);
180     arr1.position.set(length+controls.blockRadius,cube.position.y+controls.m2*2+controls1.a*2,0);
181     arr1.scale.y = controls1.a;
182     if (!controls.showAcs) {arr1.visible = false}
183     else {arr1.visible = true}
184     scene.add(arr1);
185     arr2 = new THREE.Mesh(new THREE.CylinderGeometry(0,0.7,Math.sign(controls1.a)*2,32), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
186     arr2.rotation.set(0,0,0);
187     arr2.position.set(length+controls.blockRadius,cube.position.y+controls.m2*2+controls1.a*4,0);
188     if (!controls.showAcs) {arr2.visible = false}
189     else {arr2.visible = true}
190     scene.add(arr2);
191     arr3 = new THREE.Mesh(new THREE.CylinderGeometry(0.3,0.3,4,32), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true}));
192     arr3.rotation.set(0,0,-1.5*Math.PI+controls.alpha);
193     arr3.position.set(block2.position.x-Math.sign(controls1.a)*(controls.blockRadius)*Math.cos(controls.alpha)-controls1.a*2*Math.cos(controls.alpha),block2.position.y-Math.sign(controls1.a)*(controls.blockRadius)*Math.sin(controls.alpha)-controls1.a*2*Math.sin(controls.alpha),0);
194     arr3.scale.y = controls1.a;
195     if (!controls.showAcs) {arr3.visible = false}
196     else {arr3.visible = true}
197     scene.add(arr3);
198     arr4 = new THREE.Mesh(new THREE.CylinderGeometry(0,0.7,-Math.sign(controls1.a)*2,32), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
199     arr4.rotation.set(0,0,-Math.PI/2+controls.alpha);
200     arr4.position.set(block2.position.x-Math.sign(controls1.a)*(controls.blockRadius)*Math.cos(controls.alpha)-controls1.a*4*Math.cos(controls.alpha),block2.position.y-Math.sign(controls1.a)*(controls.blockRadius)*Math.sin(controls.alpha)-controls1.a*4*Math.sin(controls.alpha),0);
201     if (!controls.showAcs) {arr4.visible = false}
202     else {arr4.visible = true}
203     scene.add(arr4);
204 
205     renderer.render(scene,camera);
206   }
207 
208   function renderScene()
209   {
210     if((block2.position.y <= controls.blockRadius) || (cube.position.y >= length*Math.tan(controls.alpha)-controls.blockRadius) || (((block2.position.y-block1.position.y)*(block2.position.y-block1.position.y)+(block2.position.x-block1.position.x)*(block2.position.x-block1.position.x)) <= 4*controls.blockRadius*controls.blockRadius)) {
211       controls1.t = 0;
212     }
213     if (controls.animate)
214     {
215       controls1.t+=dt;
216       ReDraw();
217     }
218 
219     stats.update();
220     requestAnimationFrame(renderScene);
221     renderer.render(scene,camera);
222   };
223 
224   function initStats()
225   {
226     var stats=new Stats();
227     stats.setMode(0);
228     stats.domElement.style.position='0px';
229     stats.domElement.style.left='0px';
230     stats.domElement.style.top='0px';
231     document.getElementById("Stats-output").appendChild(stats.domElement);
232     return stats;
233   };
234 
235   function onResize()
236   {
237     camera.aspect=window.innerWidth/window.innerHeight;
238     camera.updateProjectionMatrix();
239     renderer.setSize(window.innerWidth,window.innerHeight);
240   }
241 
242   window.onload = init;

Возможности программы

  • изменение угла наклона прямой

Решение частного случая

Условия задачи:

Точка подвеса маятника, состоящего из материальной точки массы [math]m[/math] на нерастяжимой нити длины [math]l[/math], движется по заданному закону [math]ξ=ξ0(t)[/math] по наклонной прямой, образующей угол [math]α[/math] с горизонтом. Составить уравнение движения маятника.

Решение:

Кинетическая энергия маятника [math]T = \frac{m{V}^2}{2}[/math] , где [math]\overline{V} = \overline{V_e} + \overline{V_r}[/math]. Здесь [math]V_e = \dot{ξ}, V_r = \dot{φ}l[/math]. Тогда квадрат скорости равен [math]{V}^2 = \dot{ξ}^2 + l^2\dot{φ}^2 + 2 l \dot{φ} \dot{ξ} cos(φ-α)[/math] и кинетическая энергия равна соответственно [math]T = \frac{m}{2}(\dot{ξ}^2 + l^2\dot{φ}^2 + 2 l \dot{φ} \dot{ξ} cos(φ-α))[/math] Потенциальная энергия будет равна [math]U = -m g l (1-cosφ)[/math]

Уравнение Лагранжа для системы с одной степенью свободы имеет вид: [math]\frac{d}{dt}(\frac{dT}{d\dot{φ}}) - \frac{dT}{d{φ}}= Q[/math]

Вычисляем производные, входящие в это уравнение
[math]\frac{dT}{d\dot{φ}} = \frac{m}{2}(2 l^2 \dot{φ} + 2 l \dot{ξ} cos(φ-α))[/math]
[math]\frac{dT}{dφ} = 0[/math]
[math]Q = \frac{dU}{dφ} = -m g l sinφ[/math]
[math]\frac{d}{dt}(\frac{dT}{d\dot{φ}}) = \frac{m}{2}(2 l^2 \dot{φ} + 2 l \dot{ξ} cos(φ-α))[/math]

Подставим полученные производные в уравнение Лагранжа: [math]m(l^2 {φ̈} + l {ξ̈} cos(φ-α)) = -m g l sinφ[/math] , поделим обе части уравнения на [math]l^2[/math] и получим


[math]{φ̈} + \frac{{ξ̈}}{l} cos(φ-α)) + \frac{g}{l} sinφ = 0[/math]