Два цилиндра (48.40)
Задача 48.40 из сборника задач Мещерского: составить уравнения движения двух цилиндров и смоделировать систему на языке программирования JavaScript.
Формулировка задачи
Шероховатый цилиндр массы m и радиуса r катится без скольжения по внутренней поверхности полого цилиндра массы M и радиуса R, могущего вращаться около своей горизонтально расположенной оси O. Моменты инерции цилиндров относительно своих осей равны
и . Составить уравнения движения системы.Решение задачи
Используем уравнение Лагранжа 2-го рода:
, где
L = T - П - функция Лагранжа T - кинетическая энергия системы П - потенциальная энергия системы q - независимые обобщенные координаты
В данной задаче в качестве обобщенных координат примем углы
и .Представим:
, где - кинетическая энергия цилиндра массы M, а - цилиндра массы m.
Полый цилиндр массы M вращается вокруг неподвижной оси, следовательно:
Движение цилиндра массы m плоское.
Где
- скорость центра масс цилиндра массой m(точки O1):
Обозначим θ - угол поворота цилиндра массы m относительно точки O1, а ω - угловая скорость вращения относительно этой точки:
Окончательно получаем T и П(определяется только силой тяжести цилиндра массой m):
Таким образом,
Найдем:
В результате получаем уравнения, описывающие движение рассматриваемой системы:
или:
Реализация на языке JavaScript
Текст программы на языке JavaScript:
Файл "4840.html"
1 <!DOCTYPE html>
2
3 <html>
4
5 <head>
6 <title>4840</title>
7 <script type="text/javascript" src="http://tm.spbstu.ru/htmlets/Barsukov\three.js"></script>
8 <script type="text/javascript" src="http://tm.spbstu.ru/htmlets/Barsukov\jquery-1.9.0.js"></script>
9 <script type="text/javascript" src="http://tm.spbstu.ru/htmlets/Barsukov\stats.js"></script>
10 <script type="text/javascript" src="http://tm.spbstu.ru/htmlets/Barsukov\dat.gui.js"></script>
11 <script type="text/javascript" src="http://tm.spbstu.ru/htmlets/Barsukov\OrbitControls.js"></script>
12 <style>
13 body{
14 /* set margin to 0 and overflow to hidden, to go fullscreen */
15 margin: 0;
16 overflow: hidden;
17 }
18 </style>
19 </head>
20 <body>
21
22 <div id="Stats-output"></div>
23 <div id="WebGL-output"></div>
24
25 <script type="text/javascript">
26
27 $(function () {
28 var stats = initStats();
29
30 var scene = new THREE.Scene();
31
32 var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
33
34 var renderer = new THREE.WebGLRenderer();
35
36 renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
37 renderer.setSize(window.innerWidth, window.innerHeight);
38 renderer.shadowMapEnabled = true;
39
40 var axes = new THREE.AxisHelper( 20 );
41 axes.position.x = -40;
42 axes.position.z = 20;
43 scene.add(axes);
44
45 var spotLight = new THREE.SpotLight( 0xffffff );
46 spotLight.position.set( -100, 0, -10 );
47 scene.add(spotLight );
48
49 var cylinder = createMesh(new THREE.CylinderGeometry(20, 20, 20,30,1,true));
50 scene.add(cylinder);
51
52 var cylinder1 = createMesh1(new THREE.CylinderGeometry(5, 5, 20, 30, 1));
53 cylinder1.position.x=0;
54 cylinder1.position.y=0;
55 cylinder1.position.z=-15;
56 scene.add(cylinder1);
57
58 var group1 = new THREE.Object3D();
59 group1.add(cylinder);
60 group1.add(cylinder1);
61 group1.position.x = 0;
62 group1.position.y = -10;
63 scene.add(group1);
64
65 function createMesh(geom) {
66 var meshMaterial = new THREE.MeshNormalMaterial();
67 meshMaterial.side = THREE.DoubleSide;
68 var wireFrameMat = new THREE.MeshBasicMaterial();
69 wireFrameMat.wireframe = true;
70 var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]);
71 return mesh;
72
73 }
74 function createMesh1(geom) {
75 var texture = THREE.ImageUtils.loadTexture("http://tm.spbstu.ru/htmlets/Barsukov\bathroom.jpg")
76 var mat = new THREE.MeshPhongMaterial();
77 mat.map = texture;
78 var mesh = new THREE.Mesh(geom, mat);
79 return mesh;
80 }
81
82 camera.position.x = 0;
83 camera.position.y = -150;
84 camera.position.z = 100;
85 camera.lookAt(scene.position);
86
87 $("#WebGL-output").append(renderer.domElement);
88 renderer.render(scene, camera);
89 var stats = initStats();
90 cameraControls = new THREE.OrbitControls(camera, renderer.domElement);
91 cameraControls.maxDistance = 100;
92 cameraControls.minDistance = 0.5;
93 cameraControls.update();
94
95 var controls = new function() {
96 this.Speed = 0.05;
97 this.Rotation = 0.01;
98 this.M1 = 0.2;
99 this.M2 = 0.05;
100 this.phi = '0';
101 }
102
103 var gui = new dat.GUI();
104 gui.add(controls, 'Speed',0,0.1);
105 gui.add(controls, 'Rotation',0,0.1);
106 gui.add(controls, 'M1',0.2,0.5);
107 gui.add(controls, 'M2',0.01,0.05);
108 gui.add(controls,'phi').listen()
109 render();
110
111 var step = 0;
112 var psi2 = 0;
113 var phi = Math.PI/2;
114 var psi = 0;
115 var phi2 = 0;
116 var phi1 = 0;
117 var psi1 = 0;
118 function render() {
119 stats.update();
120 cameraControls.update();
121 requestAnimationFrame(render);
122 renderer.render(scene, camera);
123 step += controls.Speed;
124 psi2 = (0.375*controls.M2*controls.M2)/(controls.M1*(controls.M1+controls.M2));
125 phi2 = 0.44*psi2 - 0.44*Math.sin(phi);
126 psi1 = psi1+psi2*controls.Speed;
127 phi1 = phi1+phi2*controls.Speed;
128 phi = phi+phi1*controls.Speed;
129 psi = psi+psi1*controls.Speed;
130 w = 3*phi1-4*psi1;
131 controls.phi=phi;
132 cylinder1.rotation.y = 4*w;
133 cylinder.rotation.y = w+Math.PI/2;
134 cylinder1.position.x=15*Math.sin(phi);
135 cylinder1.position.z=-15*Math.abs((Math.cos(phi)));
136 group1.rotation.z += controls.Rotation;
137 }
138
139 function initStats() {
140 var stats = new Stats();
141 stats.setMode(0); // 0: fps, 1: ms
142 stats.domElement.style.position = 'absolute';
143 stats.domElement.style.left = '0px';
144 stats.domElement.style.top = '0px';
145 $("#Stats-output").append(stats.domElement);
146 return stats;
147 }
148 });
149
150 </script>
151 </body>
152 </html>