Свободные колебания механической системы с двумя степенями свободы

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

Используемые библиотеки

  • three.js
  • dat.gui.js