Свободные колебания механической системы с двумя степенями свободы
Материал из Department of Theoretical and Applied Mechanics
Версия от 22:37, 6 июня 2018; Den.syzr (обсуждение | вклад) (Новая страница: « '''Задача:''' Смоделировать свободные колебания механической системы с двумя степенями с…»)
Задача: Смоделировать свободные колебания механической системы с двумя степенями свободы.
Исполнитель: Сызранцев Денис, гр. 23632/2.
Реализация
Код программы
1 <!DOCTYPE html>
2 <html>
3
4 <head>
5 <title>Д24 Вариант №12</title>
6 <script type="text/javascript" src="http://tm.spbstu.ru/htmlets/libs/three.min.js"></script>
7 <script type="text/javascript" src="http://tm.spbstu.ru/htmlets/libs/stats.min.js"></script>
8 <script type="text/javascript" src="http://tm.spbstu.ru/htmlets/libs/dat.gui.min.js"></script>
9 <style>
10 body{
11 /* set margin to 0 and overflow to hidden, to go fullscreen */
12 margin: 0;
13 overflow: hidden;
14 }
15 </style>
16 </head>
17 <body>
18 <table>
19 <tr>
20 <div id="Stats-output">
21 </div>
22 <div id="WebGL-output">
23 </div>
24 <div>
25 <canvas id="canvas_example1" width=1 height=1></canvas><br>
26 </div>
27 <div>
28 <canvas id="canvas_example2" width=1 height=1></canvas><br>
29 </div>
30 <script type="text/javascript">
31 var ctx1 = canvas_example1.getContext('2d');
32 var w1 = canvas_example1.width = window.innerWidth;
33 var h1 = canvas_example1.height = window.innerHeight/4;
34
35 var ctx2 = canvas_example2.getContext('2d');
36 var w2 = canvas_example2.width = window.innerWidth;
37 var h2 = canvas_example2.height = window.innerHeight/4;
38
39 var WebW = window.innerWidth;
40 var WebH = window.innerHeight/2;
41 var stats=initStats();
42 var scene=new THREE.Scene();
43 var camera=new THREE.PerspectiveCamera(45,WebW/WebH,0.1,1000);
44 var renderer=new THREE.WebGLRenderer();
45 scene.background=new THREE.Color(0xEEEEEE);
46 camera.position.set(0,0,15);
47 camera.lookAt(new THREE.Vector3(0,0,0));
48 renderer.setClearColor(new THREE.Color(0xFFFFFF,1.0));
49 renderer.setSize(WebW, WebH);
50 renderer.shadowMap.enabled=true;
51
52 var material1 = new THREE.MeshPhongMaterial( {
53 color: 0x156289,
54 emissive: 0x072534,
55 side: THREE.DoubleSide,
56 flatShading: true
57 } )
58
59 var material2 = new THREE.MeshPhongMaterial( {
60 color: 0xF9FFF5,
61 emissive: 0x072534,
62 side: THREE.DoubleSide,
63 flatShading: true
64 } )
65
66 var rc=0.2,lc=5,n=20,by=-5,sl=0.7;
67 var rod=new THREE.Mesh(new THREE.CylinderGeometry(rc,rc,lc,32,0),material1);
68 var base=new THREE.Mesh(new THREE.BoxGeometry(lc,0.7,0.7),material2);
69 base.position.set(0,by,0);
70
71 for(var k=1;k<=3;k++)
72 for(var i=0;i<=n;i++)
73 {
74 var nexus=new THREE.Mesh(new THREE.CylinderGeometry(0.05,0.05,sl),new THREE.MeshLambertMaterial({color:0xF9FFF5}));
75 nexus.name=k+"-"+i;
76 nexus.castShadow=true;
77 scene.add(nexus);
78 }
79 var ambientLight=new THREE.AmbientLight(0x0F0F0F);
80 var spotLight=new THREE.SpotLight(0xFFFFFF);
81
82 rod.castShadow=true;
83 spotLight.castShadow=true;
84
85 scene.add(base);
86 scene.add(rod);
87 scene.add(ambientLight);
88 scene.add(spotLight);
89
90 document.getElementById("WebGL-output").appendChild(renderer.domElement);
91
92 var l,m,g,c1,c2,c3;
93 var k1,k2,mu1,mu2;
94 var A1,A2,b1,b2;
95 var y0,f0,v0,w0;
96 var a11,a12,a22;
97 var c11,c12,c22;
98 var yt,ft;
99 var Y,F;
100 var t=0,dt,fl=true;
101 var cnt=new function()
102 {
103 this.dt=0.002;
104 this.y0=0.5;
105 this.f0=5;
106 this.v0=0.5;
107 this.w0=0.5;
108 this.l=1;
109 this.m=6;
110 this.g = 9.8;
111 this.c1=2000;
112 this.c2=3000;
113 this.c3=4000;
114 this.a11 = this.m;
115 this.a12 = 0;
116 this.a22 = (this.m*Math.pow(this.l,2))/3;
117 this.c11 = this.c1+this.c2+this.c3;
118 this.c12 = (this.c1+this.c2/2-this.c3)*this.l;
119 this.c22 = (this.c1+this.c2/4+this.c3)*Math.pow(this.l,2);
120 this.Y = this.m*this.g/(this.c1+this.c2+this.c3);
121 this.F = (Math.asin(2*this.m*this.g/(Math.pow(this.l,2)*(this.c3-this.c2/4-this.c1))))/2
122 this.pause=function(){fl=false;}
123 this.resume=function(){fl=true;}
124 this.redraw=function()
125 {
126 t=0;
127 y0=cnt.y0;
128 f0=Math.PI*cnt.f0/180;
129 v0=cnt.v0;
130 w0=cnt.w0;
131 dt=cnt.dt;
132 l=cnt.l;
133 m=cnt.m;
134 c1=cnt.c1;
135 c2=cnt.c2;
136 c3=cnt.c3;
137 a11=cnt.a11;
138 a12=cnt.a12;
139 a22=cnt.a22;
140 c11=cnt.c11;
141 c12=cnt.c12;
142 c22=cnt.c22;
143 Y=cnt.Y;
144 F=cnt.F;
145 scene.remove(rod);
146 scene.remove(base);
147 rod=new THREE.Mesh(new THREE.CylinderGeometry(rc,rc,l*10,32,0),material1);
148 base=new THREE.Mesh(new THREE.BoxGeometry(l*10+2,0.7,0.7),material2);
149 base.position.set(0,by,0);
150 scene.add(rod);
151 scene.add(base);
152 ctx1.clearRect(0,0,w1,h1);
153 ctx2.clearRect(0,0,w2,h2);
154 Yt = [];
155 Ft = [];
156 init();
157 };
158 };
159
160 var gui=new dat.GUI();
161 gui.add(cnt,'dt',0.001,0.005);
162 gui.add(cnt,'y0',-1,1);
163 gui.add(cnt,'f0',-15,15);
164 gui.add(cnt,'v0',-0.7,0.7);
165 gui.add(cnt,'w0',-0.7,0.7);
166 gui.add(cnt,'l',0.5,2);
167 gui.add(cnt,'m',1,12);
168 gui.add(cnt,'c1',500,10000);
169 gui.add(cnt,'c2',500,10000);
170 gui.add(cnt,'c3',500,10000);
171 gui.add(cnt,'pause');
172 gui.add(cnt,'resume');
173 gui.add(cnt,'redraw');
174 cnt.redraw();
175 render();
176
177 function render()
178 {
179 stats.update();
180 if(fl)t+=dt;
181 yt = Y+A1*Math.sin(k1*t+b1)+A2*Math.sin(k2*t+b2);;
182 ft = F+mu1*A1*Math.sin(k1*t+b1)+mu2*A2*Math.sin(k2*t+b2);
183 rod.position.y=yt;
184 rod.rotation.z=ft+Math.PI/2;
185
186 for(var k=1;k<=3;k++)
187 {
188 var ys,yf,xs,xf;
189 if(k==1){
190 ys=by;
191 yf=yt-5*l*Math.sin(ft);
192 xs = -5*l;
193 xf = -5*l*Math.cos(ft);
194 }
195 if(k==2){
196 ys=by;
197 yf=yt-5*l*Math.sin(ft)/2;
198 xs = -5*l/2;
199 xf = -5*l*Math.cos(ft)/2;
200 }
201 if(k==3){
202 ys=by;
203 yf=yt+5*l*Math.sin(ft);
204 xs = 5*l;
205 xf = 5*l*Math.cos(ft);
206 }
207 var lengty=Math.abs(ys-yf);
208 var lengtx=Math.abs(xs-xf);
209 var dly=lengty/(n+1);
210 var dlx=lengtx/(n+1);
211 for(var i=0;i<=n;i++)
212 {
213 var nexus=scene.getObjectByName(k+"-"+i);
214 nexus.position.y=ys+(i+1/2)*dly;
215 if ((k==1)||(k==2)){
216 nexus.position.x=xs+i*dlx;
217 }else{
218 nexus.position.x=xs-i*dlx;
219 }
220 if ((k==2)||(k==3)){
221 if(i%2==0)nexus.rotation.z=Math.acos(Math.sqrt(Math.pow(dly,2)+Math.pow(dlx,2))/sl);
222 else nexus.rotation.z=-Math.acos(Math.sqrt(Math.pow(dly,2)+Math.pow(dlx,2))/sl);
223 }else{
224 if(i%2==0)nexus.rotation.z=-Math.acos(Math.sqrt(Math.pow(dly,2)+Math.pow(dlx,2))/sl);
225 else nexus.rotation.z=Math.acos(Math.sqrt(Math.pow(dly,2)+Math.pow(dlx,2))/sl);
226 }
227 }
228 }
229 renderer.render(scene,camera);
230 requestAnimationFrame(render);
231 }
232 function init()
233 {
234 k1 = Math.sqrt((a11*c22+a22*c11-Math.sqrt(Math.pow(a11*c22+a22*c11,2)-4*a11*a22*(c11*c22-Math.pow(c12,2))))/(2*a11*a22));
235 k2 = Math.sqrt((a11*c22+a22*c11+Math.sqrt(Math.pow(a11*c22+a22*c11,2)-4*a11*a22*(c11*c22-Math.pow(c12,2))))/(2*a11*a22));
236 mu1 = -(c11-a11*Math.pow(k1,2))/(c12-a12*Math.pow(k1,2));
237 mu2 = -(c11-a11*Math.pow(k2,2))/(c12-a12*Math.pow(k2,2));
238 if ((f0==0)&&(y0==0)&&(w0==0)&&(v0==0)){
239 b1=Math.atan(k1*(1-mu2)/(1-mu2));
240 b2=Math.atan(k2*(1-mu1)/(1-mu1));
241 }else{
242 b1=Math.atan(k1*(f0-mu2*y0)/(w0-mu2*v0));
243 b2=Math.atan(k2*(f0-mu1*y0)/(w0-mu1*v0));
244 }
245 if ((f0==0)&&(y0==0)&&(b1==0)){
246 A1=(Math.sqrt(Math.pow((w0-mu2*v0),2)+Math.pow((k1*(f0-mu2*y0)),2)))/((mu1-mu2)*k1);
247 }else{
248 A1=(f0-mu2*y0)/(mu1-mu2)/Math.sin(b1);
249 }
250 if ((f0==0)&&(y0==0)&&(b2==0)){
251 A2=(Math.sqrt(Math.pow((w0-mu1*v0),2)+Math.pow((k2*(f0-mu1*y0)),2)))/((mu2-mu1)*k2);
252 }else{
253 A2=(f0-mu1*y0)/(mu2-mu1)/Math.sin(b2);
254 }
255 rod.position.set(0,y0,0);
256 rod.rotation.z=Math.PI/2+f0;;
257 spotLight.position.set(50,60,50);
258 for(var k=1;k<=3;k++)
259 for(var i=0;i<=n;i++)
260 {
261 var nexus=scene.getObjectByName(k+"-"+i);
262 nexus.position.set(0,rc+0.7/2,0);
263 }
264 }
265 function initStats()
266 {
267 var stats = new Stats();
268 stats.setMode(0);
269 stats.domElement.style.position='absolute';
270 stats.domElement.style.left='0px';
271 stats.domElement.style.top='0px';
272 document.getElementById("Stats-output").appendChild(stats.domElement);
273 return stats;
274 }
275
276 var Yt = [];
277 var Ft = [];
278 var dx = 10;
279
280
281 function physics(){
282 if (Yt.length > 400) Yt.shift();
283 Yt.push(yt);
284 if (Ft.length > 400) Ft.shift();
285 Ft.push(ft);
286 }
287 function draw(){
288 var N1 = Yt.length
289 var min1 = Yt[0]
290 var max1 = Yt[0]
291 for (var i = 1; i<N1; i++){
292 // if (Yt[i]<min1) min1 = Yt[i];
293 // if (Yt[i]>max1) max1 = Yt[i];
294 if (Math.abs(Yt[i]>max1)) max1 = Math.abs(Yt[i]);
295 }
296 ctx1.clearRect(0,0,w1,h1);
297 ctx1.beginPath();
298 ctx1.strokeStyle = "#000000";
299 ctx1.moveTo(dx,0);
300 ctx1.lineTo(dx,h1);
301 ctx1.moveTo(0,h1/2);
302 ctx1.lineTo(w1,h1/2);
303 //ctx1.moveTo(0,0);
304 ctx1.stroke();
305 ctx1.beginPath();
306 ctx1.strokeStyle = "#3F0CE8";
307 for (var i = 0; i<N1; i++){
308 // var plot_h1 = max1-min1;
309 // var y1 = (Yt[i]-min1)/plot_h1*h1;
310 var plot_h1 = 2*max1;
311 var y1 = Yt[i]/plot_h1*h1;
312 ctx1.lineTo(i/(N1-1)*w1,h1/2-y1);
313 }
314 ctx1.stroke();
315 var N2 = Ft.length
316 var min2 = Ft[0]
317 var max2 = Ft[0]
318 for (var i = 1; i<N2; i++){
319 //if (Ft[i]<min2) min2 = Ft[i];
320 //if (Ft[i]>max2) max2 = Ft[i];
321 if (Math.abs(Ft[i]>max2)) max2 = Math.abs(Ft[i]);
322 }
323 ctx2.clearRect(0,0,w2,h2);
324 ctx2.strokeStyle = "#000000";
325 ctx2.beginPath();
326 ctx2.moveTo(dx,0);
327 ctx2.lineTo(dx,h2);
328 ctx2.moveTo(0,h2/2);
329 ctx2.lineTo(w2,h2/2);
330 //ctx2.moveTo(0,0);
331 ctx2.stroke();
332 ctx2.beginPath();
333 ctx2.strokeStyle = "#FF0000";
334 for (var i = 0; i<N2; i++){
335 //var plot_h2 = max2-min2;
336 //var y2 = (Ft[i]-min2)/plot_h2*h2;
337 //ctx2.lineTo(i/(N2-1)*w2,h2-y2);
338 var plot_h2 = 2*max2;
339 var y2 = Ft[i]/plot_h2*h2;
340 ctx2.lineTo(i/(N2-1)*w2,h2/2-y2);
341 }
342 ctx2.stroke();
343 }
344
345 function control(){
346 physics();
347 draw();
348 }
349
350
351 window.onload=init;
352 setInterval(control, 1000/60);
353 window.addEventListener('resize', function () {
354 w1 = canvas_example1.width = window.innerWidth;
355 h1 = canvas_example1.height = window.innerHeight/4;
356 w2 = canvas_example2.width = window.innerWidth;
357 h2 = canvas_example2.height = window.innerHeight/4;
358 WebW = window.innerWidth;
359 WebH = window.innerHeight/2;
360 renderer.setSize(WebW, WebH);
361 camera.aspect = WebW / WebH;
362 });
363
364
365 </script>
366 </body>
367 </html>
Используемые библиотеки
- three.js
- dat.gui.js