Мещерский. Задача 5.8
Мещерский Задача 5.8
Визуализация 3D-задачи по статике на JavaScript
Исполнитель: Рубинова Раиса
Группа 23604/1 Кафедра Теоретической механики
Формулировка задачи[править]
Три груза A, B, C веса 10 H, 30 H и 60 H соответственно лежат на плоскости, наклоненной под углом a к горизонту. Грузы соединены тросами, как показано на рисунке. Коэффициенты трения между грузами и плоскостью Fa = 0,1, Fb = 0,25 и Fc = 0,5 соответственно. Определить угол a, при котором тела равномерно движутся вниз по плоскости. Найти также натяжения тросов Tab и Tbc
Решение задачи[править]
<syntaxhighlight lang="javascript" line start="1" enclose="div">
<!DOCTYPE html> <html> <head> <title> Задача из Мещерского </title> <script src = "three.js"> </script> <script src = "stats.min.js"> </script> <script src = "OrbitControls.js" > </script> <script src = "dat.gui.js"> </script> <style>
body { margin:0; overflow:hidden; }
</style> </head> <body>
<script>
var renderer,scene,camera,plane,stats,al,controls,c1,c2,c3,line1,line2,arr1,arr1_1,arr1_2,arr1_3,arr1_t,arr2,arr2_1,arr2_2,arr2_t,arr3,arr3_1,arr3_3,arr3_t;
///// ЗАДАНИЕ ПАРАМЕТРОВ, УКАЗАННЫХ В ЗАДАЧЕ /////
var f2 = 0.1; var f1 = 0.25; var f3 = 0.5; var P1 = 30; var P2 = 10; var P3 = 60;
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;
var planeGeometry = new THREE.PlaneGeometry(100,50,1,1); // задаем плоскость: ее ширину и высоту var planeMaterial = new THREE.MeshBasicMaterial({color: 0xDEB887}); // задаем материал и цвет плоскости plane = new THREE.Mesh(planeGeometry,planeMaterial); // создаем плоскость с заданными параметрами
//var axes = new THREE.AxisHelper(20); // создаем координатные оси //scene.add(axes);
control = new THREE.OrbitControls(camera,renderer.domElement);
controls = new function() // создаем переключатели, позволяющие изменять входные параметры { this.weightB = 30; // вес первого тела this.weightA = 10; // вес второго тела this.weightC = 60; // вес третьего тела this.coefficientB = 0.25; // коэффициент трения первого тела this.coefficientA = 0.1; // коэффициент трения второго тела this.coefficientC = 0.5; // коэффициент трения третьего тела this.displayForces = true; // модуль отображения задачи this.angle = "angle = "; // вывод полученных в ходе решения задачи значений this.angle1 = "angle = "; this.tab = "Tab = "; this.tbc = "Tbc = "; }
var gui = new dat.GUI(); // позволяем менять каждый из параметров в определенном диапазоне, в случае изменения вызываем функцию, перестраивающую выводимую на экран картинку gui.add(controls, 'weightA',0,100).onChange(ReDraw); gui.add(controls, 'weightB',0,100).onChange(ReDraw); gui.add(controls, 'weightC',0,100).onChange(ReDraw); gui.add(controls, 'coefficientB',0,1).onChange(ReDraw); gui.add(controls, 'coefficientA',0,1).onChange(ReDraw); gui.add(controls, 'coefficientC',0,1).onChange(ReDraw); gui.add(controls, 'displayForces').onChange(Change); // параметр, определяющий вариант отображения задачи (с отображением сил и без отображения) gui.add(controls, 'angle').listen(); gui.add(controls, 'angle1').listen(); gui.add(controls, 'tab').listen(); gui.add(controls, 'tbc').listen();
stats = initStats(); Draw(); renderScene(); }
/////
function Change() // функция, меняющая вариант отображения задачи { if (controls.displayForces == true) // если требуется отображение сил
{VisionTrue();}
if (controls.displayForces == false) // если не требуется отображение сил
{VisionFalse();}
}
function VisionTrue() // функция, рисующая задачу с отображением сил { ReDraw(); }
function VisionFalse() // общая картинка задача без отображения сил { ReDraw(); cm1.opacity = 1; // делаем тела непрозрачными cm2.opacity = 1; cm3.opacity = 1; arr1.visible = false; // убираем векторы, отображающие силы arr1_1.visible = false; arr1_2.visible = false; arr1_3.visible = false; arr1_t.visible = false; arr2.visible = false; arr2_1.visible = false; arr2_2.visible = false; arr2_t.visible = false; arr3.visible = false; arr3_1.visible = false; arr3_3.visible = false; arr3_t.visible = false; renderScene(); }
function ReDraw() // функция, перерисовывающая всю картинку
{
plane.remove(c1); // удаляем ранее созданные объекты
plane.remove(c2);
plane.remove(c3);
scene.remove(plane);
P1 = controls.weightB; // меняем значения параметров на те, что ввел пользователь
P2 = controls.weightA;
P3 = controls.weightC;
f1 = controls.coefficientB;
f2 = controls.coefficientA;
f3 = controls.coefficientC;
Draw();
}
function Draw() { al = Math.atan((P1*f1+P2*f2+P3*f3)/(P1+P2+P3)); controls.angle = "angle = " + al; controls.angle1 = "angle = " + 180*al/Math.PI; //alert (al);
plane.rotation.x = - 0.5*Math.PI; // задаем поворот плоскости в пространстве plane.rotation.y = - al; plane.position.x = 10; // задаем положение плоскости в пространстве plane.position.y = 0; plane.position.z = 0; scene.add(plane); // добавляем в созданную нами сцену созданную плоскость
///// СОЗДАНИЕ ТРЕХ ТЕЛ, ЛЕЖАЩИХ НА ПЛОСКОСТИ /////
var cg1 = new THREE.BoxGeometry (10,5,5); // задаем геометрию первого тела (среднее) cm1 = new THREE.MeshBasicMaterial( { opacity:0.23, color: 0xDAA520,transparent:true } ); // задаем материал 1-ого тела c1 = new THREE.Mesh(cg1,cm1); // создаем тело с заданными геометрией и материалом c1.position.z = c1.geometry.parameters.depth/2; // смещаем его центр из точки (0,0,0), чтобы тело "легло" на плоскость plane.add(c1); // добавляем тело в сцену
var cg2 = new THREE.BoxGeometry (5, 2.5, 2.5); // задаем геометрию второго тела (левое) cm2 = new THREE.MeshBasicMaterial( {opacity:0.23, color: 0xCD853F, transparent: true}); // задаем материал c2 = new THREE.Mesh(cg2,cm2); // создаем тело с заданными геометрией и материалом c2.position.z = c2.geometry.parameters.depth/2; // смещаем его центр из точки (0,0,0), чтобы тело "легло" на плоскость c2.position.x = -4*c2.geometry.parameters.width; plane.add(c2); // добавляем тело в сцену
var cg3 = new THREE.BoxGeometry (20, 10, 10); // задаем геометрию третьего тела (правое) cm3 = new THREE.MeshBasicMaterial( {opacity:0.23, color: 0xFFDEAD, transparent: true}); // задаем материал c3 = new THREE.Mesh(cg3, cm3); // создаем тело с заданными геометрией и материалом c3.position.x = 2*c3.geometry.parameters.width; // смещаем его центр из точки (0,0,0), чтобы тело "легло" на плоскость c3.position.z = c3.geometry.parameters.depth/2; plane.add(c3); // добавляем тело в сцену
///// СОЗДАНИЕ НИТЕЙ, СОЕДИНЯЮЩИХ ТЕЛА /////
var lg1 = new THREE.Geometry(); // создаем новую геометрию, предназначенную для изображения линии lg1.vertices.push(
new THREE.Vector3(c1.geometry.parameters.width/2,0,0), // задаем координату начала new THREE.Vector3(3/2*c3.geometry.parameters.width,0,0) // задаем координату конца
); var lm = new THREE.LineBasicMaterial({color: 0xA0522D}); // задаем материал line1 = new THREE.Line(lg1, lm); // задаем линию с указанными координатами и материалом c1.add(line1);
var lg2 = new THREE.Geometry(); // создаем новую геометрию, предназначенную для изображения линии lg2.vertices.push(
new THREE.Vector3(c2.geometry.parameters.width/2,0,0), // задаем координату начала new THREE.Vector3(3*c2.geometry.parameters.width,0,0) // задаем координату конца
); line2 = new THREE.Line(lg2, lm); // задаем линию с указанными координатами и материалом c2.add(line2);
///// СОЗДАНИЕ ВЕКТОРОВ, ОТОБРАЖАЮЩИХ СИЛЫ, ДЕЙСТВУЮЩИЕ НА ТЕЛА /////
var ar = new THREE.Vector3( 1, 2, 0 ); // создаем геометрию вектора, отображающего вес тела var ar1 = new THREE.Vector3 (0, 0, -1); // создаем геометрию вектора, отображающего силу тяжести, действующую на тело var origin = new THREE.Vector3( 0, 0, 0 ); // задаем точку начала var hex = 0xDC143C; // задаем цвет для веса var hex1 = 0x8B0000; // цвет, отображающий вектора силы тяжести var hex2 = 0xFF4500; // цвет, отображающий вектора сил натяжения var hex3 = 0x191970; // цвет, отображающий силы трения
var length1 = P1/2; // задаем длину (численно равную исходному параметру в задаче) arr1 = new THREE.ArrowHelper( ar, origin, length1, hex ); // создаем срелочку arr1.rotation.x = 0.5*Math.PI; // поворачиваем ее, чтобы ее ориентация соответствовала arr1.rotation.y = 0.5*Math.PI; c1.add( arr1 ); // прикрепляем вектор к первому телу
arr1_1 = new THREE.ArrowHelper (ar1, origin, length1, hex1); // создаем стрелочку arr1_1.rotation.z = al; // поворачиваем ее согласно ориентации плоскости c1.add( arr1_1); // прикрепляем к нужному телу
var ar1_3 = new THREE.Vector3( 1, 0, 0 ); // создаем геометрию вектора, отображающего натяжение нити, соединяющей первое и третье тело arr1_3 = new THREE.ArrowHelper( ar1_3, origin, P3*(f3-Math.tan(al)), hex2); // создаем стрелочку c1.add( arr1_3 ); // прикрепляем к нужному телу
controls.tbc = "Tbc = " + P3*(f3-Math.tan(al)); // вывод решения на экран
var ar1_2 = new THREE.Vector3(-1,0,0); // создаем геометрию вектора, отображающего натяжение нити, соединяющей первое и второе тело arr1_2 = new THREE.ArrowHelper( ar1_2, origin, P2*(Math.tan(al)-f2), hex2); // создаем стрелочку c1.add( arr1_2 ); // прикрепляем к нужному телу
controls.tab = "Tab = " + P2*(Math.tan(al)-f2); // вывод решения на экран
arr1_t = new THREE.ArrowHelper( ar1_3, origin, f1*length1, hex3); // создаем вектор, отображающий силу трения c1.add( arr1_t ); // прикрепляем к нужному телу
var length2 = P2/2; // задаем длину (численно равную исходному параметру в задаче) arr2 = new THREE.ArrowHelper( ar, origin, length2, hex ); // создаем срелочку arr2.rotation.x = 0.5*Math.PI; // поворачиваем ее, чтобы ее ориентация соответствовала arr2.rotation.y = 0.5*Math.PI; c2.add( arr2 ); // прикрепляем вектор ко второму телу
arr2_2 = new THREE.ArrowHelper (ar1, origin, length2, hex1); // создаем стрелочку arr2_2.rotation.z = al; // поворачиваем ее согласно ориентации плоскости c2.add( arr2_2); // прикрепляем к нужному телу
var ar2_1 = new THREE.Vector3( 1, 0, 0); // создаем геометрию вектора, отображающего натяжение нити, соединяющей второе и первое тело arr2_1 = new THREE.ArrowHelper( ar2_1, origin, P2*(Math.tan(al)-f2), hex2); // создаем стрелочку c2.add( arr2_1 ); // прикрепляем к нужному телу
arr2_t = new THREE.ArrowHelper( ar1_3, origin, f2*length2, hex3); // создаем вектор, отображающий силу трения c2.add( arr2_t ); // прикрепляем к нужному телу
var length3 = P3/2; // задаем длину (численно равную исходному параметру в задаче) arr3 = new THREE.ArrowHelper( ar, origin, length3, hex ); // создаем срелочку arr3.rotation.x = 0.5*Math.PI; // поворачиваем ее, чтобы ее ориентация соответствовала arr3.rotation.y = 0.5*Math.PI; c3.add( arr3 ); // прикрепляем вектор к третьему телу
var ar3_1 = new THREE.Vector3( -1, 0, 0); // создаем геометрию вектора, отображающего натяжение нити, соединяющей третье и первое тело arr3_1 = new THREE.ArrowHelper( ar3_1, origin, P3*(f3-Math.tan(al)), hex2); // создаем стрелочку c3.add( arr3_1 ); // прикрепляем к нужному телу
arr3_3 = new THREE.ArrowHelper (ar1, origin, length3, hex1); // создаем стрелочку arr3_3.rotation.z = al; // поворачиваем ее согласно ориентации плоскости c3.add( arr3_3); // прикрепляем к нужному телу
arr3_t = new THREE.ArrowHelper( ar1_3, origin, f3*length3, hex3); // создаем вектор, отображающий силу трения c3.add( arr3_t ); // прикрепляем к нужному телу
camera.position.x = -30; // задаем местоположение камеры camera.position.y = 40; camera.position.z = 30; camera.lookAt(scene.position); document.getElementById("WebGL").appendChild(renderer.domElement);
renderer.render(scene,camera); }
function renderScene() { stats.update(); P1 = controls.weightB; P2 = controls.weightA; P3 = controls.weightC; f1 = controls.coefficientB; f2 = controls.coefficientA; f3 = controls.coefficientC; requestAnimationFrame(renderScene); renderer.render(scene,camera); }
function initStats() //window in the left corner
{
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() //moving of camera {
camera.aspect = window.innerWidth/window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth,window.innerHeight);
}
window.onload = init; window.addEventListener('resize',onResize,true);
</script>