Текущая версия |
Ваш текст |
Строка 1: |
Строка 1: |
− | Мещерский Задача 47.11
| + | ==Решение задачи== |
− | | |
− | Визуализация 3D-задачи по динамике на JavaScript
| |
− | | |
− | Исполнитель: [[Ершов_Александр|Ершов Александр]]
| |
− | | |
− | Группа 23632/2 Кафедра Теоретической механики
| |
− | | |
− | ==Условие задачи== | |
− | Каток A массы M1, скатываясь без скольжения по наклонной плоскости вниз, поднимает посредством нерастяжимой нити, переброшенной через блок B, груз C массы M2. При этом блок B вращается вокруг неподвижной оси O, перпендикулярной его плоскости. Каток A и блок B — однородные круглые диски одинаковой массы и радиуса. Наклонная плоскость образует угол α с горизонтом. Определить ускорение оси катка. Массой нити пренебречь.
| |
− | | |
− | ==Решение==
| |
− | <math> Φ_i = -m_i a_i</math><br/>
| |
− | <math>M_i = -J_i ε_i</math><br/>
| |
− | Для блока А:<br/>
| |
− | <math> Φ_A = m_1 a_A</math><br/>
| |
− | <math>M_A = -J_{CA} ε_A = \frac{m_{1} R_{1}^2}{2} \frac{a_A}{R}</math><br/>
| |
− | Для блока В:<br/>
| |
− | <math>M_B = -J_sB ε_B = \frac{m_{1} R_{1}^2}{2} \frac{a_A}{R}</math><br/>
| |
− | Для груза С:<br/>
| |
− | <math> Φ_C = m_2 a_C = m_2 a_A</math><br/>
| |
− | | |
− | <math>\sum\ δA_{i} = m_1 g sinα δS_A - Φ_1 δS - M_A δφ_A - M_B δφ_B - m_2 g δS_C - Φ_2 δS_C = 0</math><br/>
| |
− | <math>m_1 g sinα δS_A - m_1 a_A δS_A - \frac{m_{1} R a_A δS_A}{2 R} - \frac{m_{1} a_A δS_A}{2} - m_2 g δS_A - m_2 a_A δS_A = 0</math><br/>
| |
− | <math>a_A = \frac{m_1 g sinα - m_2 g}{m_1 + \frac{m_1}{2} + \frac{m_1}{2} + m_2} = \frac{m_1 g sinα - m_2 g}{2 m_1 + m_2}</math><br/>
| |
− | | |
− | Ответ: <math>a_A = \frac{m_1 g sinα - m_2 g}{2 m_1 + m_2}</math>
| |
− | | |
− | ==Визуализация==
| |
| | | |
| {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Ershov_AD/index.html |width=850 |height=400 |border=0 }} | | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Ershov_AD/index.html |width=850 |height=400 |border=0 }} |
− |
| |
− | ==Код программы==
| |
− | <div class="mw-collapsible mw-collapsed">
| |
− | '''Текст программы на языке JavaScript:''' <div class="mw-collapsible-content">
| |
− | <syntaxhighlight lang="javascript" line start="1" enclose="div">
| |
− | var renderer, scene, camera, stats, axes;
| |
− | var control, controls, controls1, spotLight;
| |
− | var plane1, plane2, plane3, block1, block2, torus, cube, arr1, arr2, arr3, arr4, cr1,cr2,cr3;
| |
− | var dt = 1/60;
| |
− | var g = 9.8;
| |
− | var length = 30;
| |
− | var cubeY = 25;
| |
− | ///// ЗАДАНИЕ ПАРАМЕТРОВ, УКАЗАННЫХ В ЗАДАЧЕ /////
| |
− |
| |
− | function init()
| |
− | {
| |
− | scene = new THREE.Scene(); // создаем сцену
| |
− | camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000); // создаем камеру
| |
− |
| |
− | renderer = new THREE.WebGLRenderer();
| |
− | renderer.setClearColor(0XEEEEEE,1);
| |
− | renderer.setSize(window.innerWidth,window.innerHeight);
| |
− | renderer.shadowMap.enabled=true;
| |
− |
| |
− | axes = new THREE.AxisHelper(20); // создаем координатные оси
| |
− | scene.add(axes);
| |
− |
| |
− |
| |
− |
| |
− | control = new THREE.OrbitControls(camera,renderer.domElement);
| |
− |
| |
− | controls = new function() // создаем переключатели, позволяющие изменять входные параметры
| |
− | {
| |
− | 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>
| |
− |
| |
− | </div>
| |