Интерактивная модель простейшей автоколебательной системы с пружиной

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
Виртуальная лаборатория > Простейшая колебательная система с двумя степенями свободы

Рассматривается простейшая колебательная система тело-пружина. Пружина крепится на неподвижном стержне, заделанном в центре движущейся круглой пластины.

Уравнения движения системы будут выглядеть так:

[math] m \ddot{z} + F'(V) \dot{z} + c z = 0 [/math]


Скачать IMoS-OSWaS.rar.

Текст программы на языке JavaScript (разработчик Сергей Бондарев):

Файл "2_1.js"

  1 function MainParticle(canvas, canvas_gr, canvas_gr2) {
  2     // Предварительные установки
  3     var context    = canvas.getContext("2d");  // на context происходит рисование
  4 	var context_gr = canvas_gr.getContext("2d");  // на context происходит рисование
  5 	var context_gr2 = canvas_gr2.getContext("2d");
  6 	
  7    //  Задание констант	
  8     const Pi = 3.1415926;                   // число "пи"
  9     const m0 = 1;                           // масштаб массы
 10     const T0 = 1;                           // масштаб времени (период колебаний исходной системы)
 11     const a0 = 1;                           // масштаб расстояния (диаметр шара)
 12 
 13     const g0 = a0 / T0 / T0;                // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
 14     const k0 = 2 * Pi / T0;                 // масштаб частоты
 15     const C0 = m0 * k0 * k0;                // масштаб жесткости
 16 	var scale1 = 0.2;
 17 	var scale2 = 0.2;
 18   
 19 
 20     // *** Задание физических параметров ***
 21 	var xShift= 0;
 22     const Ny = 15;                           // число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
 23     const Nx = 15;							 // число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
 24 	const l1 =  15*a0;						// длина первой пружины
 25 	const l2 =  5*a0;						// длина второй пружины
 26 	var m1 = 5 * m0;  						// масса первого шара
 27 	var m2 = 10 * m0; 						// масса второго шара
 28     const Cwall = 10 * C0;                  // жесткость стен
 29     const r = 1 * a0;                     // радиус частицы в расчетных координатах
 30 	var c1 = 100;                    	    // "жесткость" пружинки 1
 31 	var c2 = 100;                     		// "жесткость" пружинки 1
 32 	var vx0 = 0 * a0/T0;					//начальная скорость
 33 	var delt = 0*a0;						//начальное смещение
 34 	var E = 0;								//энергия системы
 35 	var Vmax = 0; var Mmin = 0; var Vprov = 0;
 36 
 37 
 38 	//*** Передача значений слайдерам и текстовым окнам***
 39 	Text_delt.value  = delt;
 40 	Text_m1.value  = m1;
 41 	//Text_m2.value  = m2;
 42 	Text_c1.value  = c1;
 43 	//Text_c2.value  = c2;
 44 	
 45 	Slider_delt.min = -1;          			
 46     Slider_delt.max = 1;
 47     Slider_delt.step = 0.1;
 48     Slider_delt.value = Text_delt.value;  
 49 	
 50 	Slider_m1.min = 0.1;          
 51     Slider_m1.max = 10;
 52     Slider_m1.step = 0.1;
 53     Slider_m1.value = Text_m1.value; 
 54 	
 55 	//Slider_m2.min = 0.1;          
 56     //Slider_m2.max = 10;
 57     //Slider_m2.step = 0.1;
 58    // Slider_m2.value = Text_m2.value; 
 59 	
 60 	//Slider_c2.min = 1;     				  
 61    // Slider_c2.max = 200;				
 62    // Slider_c2.step = 1;					
 63    //Slider_c2.value = Text_c2.value;
 64     Slider_c1.min = 1;   
 65     Slider_c1.max = 200;
 66     Slider_c1.step = 1;	
 67     Slider_c1.value = Text_c1.value; 	
 68 	Slider_delt.focus();
 69 	
 70     // *** Задание вычислительных параметров ***
 71 
 72     const fps = 550;                         // frames per second - число кадров в секунду (качеcтво отображения)
 73     const spf = 260;                        // steps per frame   - число шагов интегрирования между кадрами (скорость расчета)
 74     const dt  = 0.01 * T0 / fps;           // шаг интегрирования 
 75 	
 76 	// Задание констант для рисования
 77 	const scale    = canvas.height / Ny / a0;  // масштабный коэффициент для перехода от расчетных к экранным координатам
 78 	const scale_gr = canvas_gr.height / Ny / a0;  // масштабный коэффициент для перехода от расчетных к экранным координатам
 79 	const scale_gr2 = canvas_gr2.height / Ny / a0;
 80 	
 81 	
 82     var w = canvas.width / scale;		 // ширина окна в расчетных координатах
 83 	var h = canvas.height / scale;       // высота окна в расчетных координатах
 84 	var w1 = canvas_gr.width / scale;		 // ширина окна в расчетных координатах
 85 	var h1 = canvas_gr.height / scale;       // высота окна в расчетных координатах
 86              
 87 	
 88     // -------------------------------         Выполнение программы              ------------------------------------------
 89 	// Добавление шара 1
 90     var b = [];
 91 	var time = 1;
 92 	b.x  = l1;            b.y   = h / 2;   // расчетные координаты шара
 93 	b.x_ = b.x;              b.y_  = b.y; 
 94 	b.fx = 0;                b.vx = 0;               // начальная скорость
 95 	// Добавление шара 2
 96 	var c = [];
 97 	c.x  = l2 + l1;    		 c.y   = h / 2;   // расчетные координаты шара
 98 	c.x_ = c.x;              c.y_  = c.y; 
 99 	c.fx = 0;              	c.vx = 0;                // начальная скорость
100 
101 	
102 	// центр рамки 
103 	var origin = [];
104 	origin.x = w/2;	origin.y = h/2;
105 	// стенка 
106 	var wall1 = [];
107 	wall1.x = w/2 - 9*a0;	wall1.y = h/2;
108 
109 	// Основной цикл программы
110 	setInterval(control, 1500 / fps);  // функция control вызывается с периодом, определяемым вторым параметром
111 	
112 // ---------------------------------------------------------------------------------------------------------------------
113 // ---------------------------------           Определение всех функций              -----------------------------------
114 // ---------------------------------------------------------------------------------------------------------------------
115 	
116 	// функция запускается при нажатии клавиши мыши
117     canvas.onmousedown = function(e) 
118 	{
119         var m = mouseCoords(e);                     // получаем координаты курсора мыши
120 		context.clearRect(0, 0, w * scale, h* scale);      
121 		context_gr.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);      
122 		context_gr2.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);  
123         context_gr.closePath();
124 		context_gr2.closePath();
125 		context.closePath();
126         context.fill();
127         var x = b.x*scale - m.x;                     // расстояние от центра шара до курсора по оси x
128         var y = b.y*scale - m.y;  					 // расстояние от центра шара до курсора по оси y
129         var rLen2 = x * x + y * y;                   // квадрат расстояния между курсором и центром шара
130 		//console.log(rLen2);
131 		//console.log(100*r*r);
132         if (rLen2 <= 500 * r * r)					 // если курсор нажал на шар
133 		{                       
134             xShift = b.x*scale - m.x;                // сдвиг курсора относительно центра шара по x
135             canvas.onmousemove = mouseMove; 		 // пока клавиша нажата - работает функция перемещения
136 			
137         }
138     }
139  
140     // функция запускается при отпускании клавиши мыши
141     document.onmouseup = function() 
142 	{
143         canvas.onmousemove = null;        // когда клавиша отпущена - функции перемещения нету
144     }
145  
146     // функция запускается при перемещении мыши (много раз, в каждый момент перемещения)
147     // в нашем случае работает только с зажатой клавишей мыши
148     function mouseMove(e) {
149 		context.clearRect(0, 0, w * scale, h* scale);      
150 		context_gr.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);      
151 		context_gr2.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);  
152         var m = mouseCoords(e); 		// получаем координаты курсора мыши
153         b.x = (m.x + xShift)/scale;
154 		delt = b.x - l1;
155 		b.vx = 0; c.vx = 0; 
156 		console.log(b.x);
157 		Text_delt.value  = delt;
158 		Slider_delt.value = Text_delt.value;  
159 		//var scale1 = 0.0000000002;
160 		//var scale2 = 0.2;
161 		
162     }
163  
164     // функция возвращает координаты курсора мыши
165     function mouseCoords(e) {
166         var m = [] ;
167         var rect = canvas.getBoundingClientRect();
168         m.x = e.clientX - rect.left;
169         m.y = e.clientY - rect.top;
170         return m;
171     }
172 	// основная функция, вызываемая в программе
173 	function control() 
174 	{
175         physics(); // делаем spf шагов интегрирование
176 		draw();
177 		draw_gr();
178 		draw_gr2();
179 		
180     }
181 
182 	// Реакция на изменение значения в чекбоксе
183 	this.set_delt = function(input) 
184 	{
185 		delt = Number(input);   		//записываем значение начального смещения
186 		time = 1;
187 		b.x = l1 + delt; c.x = l1+l2;   //изменение начальных координат шаров   
188 		b.x_ = b.x; 
189 		b.vx = 0; c.vx = 0; 			//задание начальных скоростей шаров
190 		Text_delt.value  = delt;
191 		Slider_delt.value = Text_delt.value;  
192         context.clearRect(0, 0, w * scale, h* scale);      
193 		context_gr.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);      
194 		context_gr2.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);  
195 		
196 	}
197 	
198 	this.set_m1 = function(input) 
199 	{
200 		m1 = Number(input);   
201 		time = 1;
202         context.clearRect(0, 0, w * scale, h* scale);      
203 		context_gr.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);      
204 		context_gr2.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);   
205 	}
206 	
207 	this.set_c1 = function(input) 
208 	{
209 		c1 = Number(input);   
210 		time = 1;
211       context.clearRect(0, 0, w * scale, h* scale);      
212 		context_gr.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);      
213 		context_gr2.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);   
214 		
215 	}
216 	
217 	this.set_m2 = function(input) 
218 	{
219 		m2 = Number(input);   
220 		time = 1;
221     context.clearRect(0, 0, w * scale, h* scale);      
222 		context_gr.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);      
223 		context_gr2.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);  
224 	}
225 	
226 	this.set_c2 = function(input) 
227 	{;
228 		c2 = Number(input);   
229 		time = 1;
230         context.clearRect(0, 0, w * scale, h* scale);      
231 		context_gr.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);      
232 		context_gr2.clearRect(0, 0, w1 * scale_gr, h1 * scale_gr);  
233 	}
234 	
235 	/*this.set_scale1 = function(input) 
236 	{
237 		//scale1 = Number(input); 
238 		var Cmax = Math.max(c1, c2); var Mmax = Math.max(m1, m2); 
239 		scale1 =  h*Mmax/(Cmax*delt);
240 		console.log(scale1);
241 		time = 1;
242         context.clearRect(0, 0, w * scale, h * scale);  
243 		context_gr.clearRect(0, 0, w * scale, h * scale);
244 		context_gr2.clearRect(0, 0, w * scale, h * scale); 
245 	}
246 	
247 	this.set_scale2 = function(input) 
248 	{
249 		
250 		scale2 = Number(input);   
251 		time = 1;
252         context.clearRect(0, 0, w * scale, h * scale);  
253 		context_gr.clearRect(0, 0, w * scale, h * scale);
254 		context_gr2.clearRect(0, 0, w * scale, h * scale); 
255 	}*/
256 	
257     // Функция, делающая spf шагов интегрирования
258     function physics()
259 	{     
260         b.x_ = b.x;  b.vx_= b.vx;									//записываем старые координаты и скорости
261 		c.x_ = c.x;  c.vx_= c.vx;
262 		E_ = E;
263 		 
264 			for (var s = 1; s <= spf; s++) 	
265 			{
266 			
267 			b.vx  +=  (c2*(-b.x + c.x - l2) - c1*(b.x - l1))/m1*dt; //расчет скорости первого шара
268 			c.vx  += -c2*(c.x - b.x - l2)/m2*dt;					//расчет скорости второго шара
269 			b.x += b.vx*dt;											//расчет координаты первого шара
270 			c.x += c.vx*dt;											//расчет координаты второго шара
271 			E = 0.5*(m1*b.vx*b.vx + m2*c.vx*c.vx)+0.5*c2*(c.x - b.x -l2)*(c.x - b.x -l2)+0.5*c1*(b.x-l1)*(b.x - l1); //рачсет энергии системы
272 			//Vprov = Math.max(b.vx, c.vx);
273 			//if ((Vprov) > Vmax) Vmax = b.vx;		   
274 		  
275 		 
276 			}
277 	  
278 	   time = time + 1;
279 	   
280     }
281 	
282     // определение функций, рисующих частицу, стенки и графики
283     
284     function draw() //функция, рисующая шары, стенку и пружины
285 	{
286 			context.clearRect(0, 0, w * scale, h * scale);      // очистить экран
287            
288 		    // линия, соединяющая первую частицу со стенкой
289 		   	context.beginPath();
290 			context.moveTo(b.x*scale, b.y*scale);
291         	context.lineTo(wall1.x*scale, wall1.y*scale);
292 			// линия, соединяющая первую частицу со второй
293 			/* context.moveTo(b.x*scale, b.y*scale);
294         	context.lineTo(c.x*scale, c.y*scale);	 */
295 			// стенка 
296 			context.moveTo(wall1.x*scale, (wall1.y + a0)*scale );
297         	context.lineTo(wall1.x*scale, (wall1.y - a0)*scale );	
298 			context.closePath();
299 			context.stroke();
300 			
301 			// частица вторая
302 			/* context.fillStyle = "red";
303 			context.beginPath();
304             context.arc(c.x * scale, c.y * scale, 0.5*r * scale, 0,  2*Math.PI, false);
305 			context.fill(); */
306 			//частица первая
307 			context.fillStyle = 'blue';
308          	context.beginPath();
309             context.arc(b.x * scale, b.y * scale, 0.5*r * scale, 0,  2*Math.PI, false);
310 			context.fill();
311 			
312 			
313     }
314 
315 
316 	
317 	function draw_gr() // Определение функции, рисующей первый график
318 	{
319 		scale2 = h /5* delt;
320 		//Graph1(c, 'red'); //график для второго шара
321 		Graph(b, 'blue'); //график для первого шара
322 		GraphAxex('black');	//оси
323 				
324     }
325 	
326 	
327 	
328 	
329 	function Graph(b, color)
330     {
331          
332         context_gr.strokeStyle = color;
333         context_gr.beginPath();
334 	    context_gr.moveTo(time*scale2/3, (b.x-l1)*scale*2*scale2 + h1*scale/2);
335 	    context_gr.lineTo( (time+1)*scale2/3, (b.x_- l1)*scale*2*scale2 + h1*scale/2);
336 		context_gr.stroke();
337         context_gr.closePath();
338 		
339     }  
340 	
341 	function GraphAxex(color)
342 	{
343 		context_gr.strokeStyle = color;
344         context_gr.beginPath();
345 	  	// ось горизонтальная
346 		context_gr.moveTo(w1/2*scale, 0);
347 		context_gr.lineTo(w1/2*scale, h1*scale);
348 		// ось вертикальная
349 		context_gr.moveTo(0, (h1/2)*scale);
350 		context_gr.lineTo((w1)*scale, (h1/2)*scale);
351         context_gr.closePath();
352 		context_gr.stroke();
353 	
354 	}
355 	
356 	function Graph1(b, color)
357     {
358          
359         context_gr.strokeStyle = color;
360         context_gr.beginPath();
361 		context_gr.moveTo(time*scale2/3, (b.x-l1-l2)*scale*2*scale2 + scale*h1/2);
362 		context_gr.lineTo( (time+1)*scale2/3, (b.x_- l1-l2)*scale*2*scale2 + scale*h1/2);
363 		context_gr.stroke();
364 		context_gr.closePath();
365 		
366     }  
367 	
368 	
369 	function draw_gr2() // Определение функции, рисующей второй график
370 	{
371 	
372 		var Mmax= Math.max(m1, m2);
373 		scale1 = 6* (h1*Mmax)/( (c1+c2)*delt*delt);		 
374 		GraphVel(b, 'blue'); //график для первого шара
375 		//GraphVel2(c, 'red'); //график для второго шара
376 		GraphAxex2('black'); //оси	
377 		
378   			
379     }
380 	
381 	function GraphVel(b, color)
382     {
383         
384 		
385         context_gr2.strokeStyle = color;
386       
387 		context_gr2.beginPath();
388 		
389 		context_gr2.moveTo((b.x-l1)*2*scale1 + scale*w1/2, b.vx*scale1 + scale*h1/2 );
390 		context_gr2.lineTo((b.x_- l1)*2*scale1 + scale*w1/2, b.vx_*scale1 + scale*h1/2);
391 		
392 		context_gr2.closePath();
393 		context_gr2.stroke();	
394 		
395         
396     }
397 	
398 	    function GraphVel2(b, color)
399     {
400          
401         context_gr2.strokeStyle = color;
402       
403 		context_gr2.beginPath();
404 		
405 		context_gr2.moveTo((b.x-l1-l2)*2*scale1 + scale*w1/2, b.vx*scale1 + scale*h1/2 );
406 		context_gr2.lineTo((b.x_- l1-l2)*2*scale1 + scale*w1/2, b.vx_*scale1 + scale*h1/2);
407 		
408 		
409 		context_gr2.closePath();
410 		context_gr2.stroke();	
411 		
412 		
413         
414     }
415 	
416 	function GraphAxex2(color)
417 	{
418 		context_gr2.strokeStyle = color;
419         context_gr2.beginPath();
420 	  	// ось горизонтальная
421 		context_gr2.moveTo(w1/2*scale, 0);
422 		context_gr2.lineTo(w1/2*scale, h1*scale);
423 		// ось вертикальная
424 		context_gr2.moveTo(0, (h1/2)*scale);
425 		context_gr2.lineTo((w1)*scale, (h1/2)*scale);
426         context_gr2.closePath();
427 		context_gr2.stroke();
428 	
429 	}
430 	 
431  
432 }

Файл "1_1.html"

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title> 2 </title>
 5     <script src="2_1.js"></script>
 6 </head>
 7 <body>
 8 	<!-- Добавление области для рисования частицы -->
 9     <canvas id="canvasBalls" width="800" height="300" style="border:1px solid #000000;"></canvas>
10 	<!-- Добавление области для рисования графика -->
11 	 <div>
12         Координаты от времени:
13         <font color="#0000FF" size="5"><B></B></font> Первое тело
14         
15        <!-- <font color="#FF0000" size="5"><B>—</B></font> Второе тело -->
16         
17     </div>    
18 	<canvas id="canvasGraph" width="800" height="600" style="border:1px solid #000000;"></canvas>	
19 	<!-- Добавление чекбокса для ввода скорости частицы -->
20 	<div>
21          Фазовая плоскость:
22         <font color="#0000FF" size="5"><B></B></font> Первое тело
23         
24        <!-- <font color="#FF0000" size="5"><B>—</B></font> Второе тело -->
25         
26     </div>     	
27 	<canvas id="canvasGraph1" width="800" height="600" style="border:1px solid #000000;"></canvas>	
28 	
29     <div>
30 	    delt =
31         <input id="Text_delt" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
32             if (!this.checkValidity()) return;
33             app.set_delt(this.value);
34 			document.getElementById('Slider_delt').value = this.value;
35            
36         ">
37 		<input type = "range"  id="Slider_delt" style="width: 100px;" oninput="app.set_delt(this.value); document.getElementById('Text_delt').value = this.value;">
38         </I></font>
39     </div>
40 	
41 	<!-- Масса 1 -->
42 	<div>
43 	    m1 =
44         <input id="Text_m1" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
45             if (!this.checkValidity()) return;
46             app.set_m1(this.value);
47             document.getElementById('Slider_m1').value = this.value;
48         ">
49 		<input type = "range"  id="Slider_m1" style="width: 100px;" oninput="app.set_m1(this.value); document.getElementById('Text_m1').value = this.value;">
50         </I></font>
51     </div>
52 	
53 	<!-- Жесткость 1-->
54 	<div>
55 	    c1 =
56         <input id="Text_c1" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
57             if (!this.checkValidity()) return;
58             app.set_c1(this.value);
59             document.getElementById('Slider_c1').value = this.value;
60         ">
61 		<input type = "range"  id="Slider_c1" style="width: 100px;" oninput="app.set_c1(this.value); document.getElementById('Text_c1').value = this.value;">
62         </I></font>
63     </div>
64 	
65     <script type="text/javascript"> app = new MainParticle(document.getElementById('canvasBalls'),document.getElementById('canvasGraph'),document.getElementById('canvasGraph1'));</script>
66 </body>
67 </html>