КП: Моделирование пружин

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
Кафедра ТМ > Программирование > Интернет > JavaScript > Моделирование фигур Лиссажу при помощи пружин

Если у вас отображается старая версия программы - нажмите "Ctrl + F5"


Левая клавиша мыши по грузу - перетаскивание.

Левая клавиша мыши по полю - заморозить систему.

По умолчанию выбрано простое движение(учитывание только силы упругости вдоль оси), для выбора сложного движения, приближенного к реальному выберите "Сложное движение" снизу страницы (сложное движение - учитывается и сила упругости, и сила деформации пружины действующая под углом)


Не удается найти HTML-файл BogdanovSpring_TM.html

Текст программы на языке JavaScript (разработчики Богданов Дмитрий, использована библиотека oCanvas): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> Файл "script.js"

  1 function MainMech(canvas, slider_m, text_m, slider_Cx, text_Cx, slider_Cy, text_Cy, slider_B, text_B, check) {
  2  
  3     // *** Задание физических параметров ***
  4  
  5     var m = 1;                     // масса
  6     var Cx = 1;                     // жесткость X
  7     var Cy = 1;                     // жесткость Y
  8     var B = 0;                    // вязкость
  9  
 10     // *** Задание вычислительных параметров ***
 11  
 12     const fps = 24;             // frames per second - число кадров в секунду (качечтво отображения)
 13 //    const fps = 4 * 29;               // frames per second - число кадров в секунду (качечтво отображения)
 14     const spf = 10;             // steps per frame   - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета)
 15     const dt  = 0.1  / fps;        // шаг интегрирования (качество расчета)
 16     var steps = 0;                      // количество шагов интегрирования
 17  
 18     // Установка слайдеров значений
 19  
 20 
 21 	
 22     // функции, запускающиеся при перемещении слайдера
 23     this.setSlider_m = function(new_m){m = new_m;};           // new_m - значение на слайдере
 24     this.setSlider_Cx = function(new_Cx){Cx = new_Cx;};
 25     this.setSlider_Cy = function(new_Cy){Cy = new_Cy;};
 26     this.setSlider_B = function(new_B){B = new_B ;};
 27  
 28     slider_m.min = 1;               slider_m.max = 10;
 29     slider_m.step = 0.10;
 30     slider_m.value = m;          // начальное значение ползунка должно задаваться после min и max
 31     text_m.value = m.toFixed(2);
 32     slider_Cx.min = 1.00;               slider_Cx.max = 10.00;
 33     slider_Cx.step = 0.10;
 34     slider_Cx.value = Cx;                // начальное значение ползунка должно задаваться после min и max
 35     text_Cx.value = Cx.toFixed(2);
 36 	 slider_Cy.min = 1.00;               slider_Cy.max = 10.00;
 37     slider_Cy.step = 0.10;
 38     slider_Cy.value = Cy;          // начальное значение ползунка должно задаваться после min и max
 39     text_Cy.value = Cy.toFixed(2);
 40     slider_B.min = 0.00;               slider_B.max = 10.00;
 41     slider_B.step = 0.10;
 42     slider_B.value = B;                // начальное значение ползунка должно задаваться после min и max
 43     text_B.value = B.toFixed(2);
 44  
 45     var count = true;       // проводить ли расчет системы
 46     var vx = 0;              // скорость тела X
 47     var vy = 0;              // скорость тела Y
 48  
 49     // создаем объект, связанный с элементом canvas на html странице
 50     var ocanvas = oCanvas.create({
 51         canvas: "#canvasMech",          // canvasMech - id объекта canvas на html странице
 52         fps: fps                        // сколько кадров в секунду
 53     });
 54  
 55     var rw = canvas.width / 30;     var rh = canvas.height / 30;
 56     var x0 = 15 * rw ;      var y0 = 15 * rh ;
 57 	
 58 	var R0 = y0; 
 59  
 60     // создаем пружину
 61     const coil = 15;        // количество витков
 62     
 63     const startX1 = 0;       // закрепление пружины
 64     const startY1 = y0;       // закрепление пружины
 65     const startX2 = canvas.width;       // закрепление пружины
 66     const startY2 = y0;       // закрепление пружины
 67     const startX3 = x0;       // закрепление пружины
 68     const startY3 = 0;       // закрепление пружины
 69     const startX4 = x0;       // закрепление пружины
 70     const startY4 = canvas.height;       // закрепление пружины
 71     this.clearCanvas = function()
 72 	{
 73 	};
 74     
 75     var lines1 = [];         // этот массив будет содержать ссылки на линии 1й пружины
 76     var lines2 = [];         // этот массив будет содержать ссылки на линии 2й пружины
 77     var lines3 = [];         // этот массив будет содержать ссылки на линии 3й пружины
 78     var lines4 = [];         // этот массив будет содержать ссылки на линии 4й пружины
 79     for (var i = 0; i < coil; i++ ) {
 80         lines1[i] = ocanvas.display.line({
 81             start: { x: 0, y:0 },
 82             end: { x: 0, y: 0 },
 83             stroke: "1px #000000"
 84         }).add();
 85         lines2[i] = ocanvas.display.line({
 86             start: { x: 0, y:0 },
 87             end: { x: 0, y: 0 },
 88             stroke: "1px #000000"
 89         }).add();
 90         lines3[i] = ocanvas.display.line({
 91             start: { x: 0, y:0 },
 92             end: { x: 0, y: 0 },
 93             stroke: "1px #000000"
 94         }).add();
 95         lines4[i] = ocanvas.display.line({
 96             start: { x: 0, y:0 },
 97             end: { x: 0, y: 0 },
 98             stroke: "1px #000000"
 99         }).add();
100     }
101     
102     // создаем прямоугольник
103     var ellipse = ocanvas.display.ellipse({x: x0, y: y0, radius: 5 * m, fill: "rgba(255, 0, 0, 1)"}).add();
104  
105     // захват прямоугольника мышью
106     ellipse.dragAndDrop({
107         changeZindex: true,             // если много объектов - захваченный будет нарисован спереди
108         start: function ()  { count = false; trajectory = [];    this.fill = "rgba(255, 0, 0, 0.5)"; },  // отключаем расчет и делаем объект полупрозрачным
109         move:  function ()  {  vx = 0;  vy = 0;      drawSpring();},             // перемещение 
110         end: function ()    { count = true;      this.fill = "rgba(255, 0, 0, 1)"; }     // включаем расчет и убираем полупрозрачность
111     });
112  
113     ocanvas.bind("mousedown", function () {count = false;});    // заморозить фигуру при клике на поле 
114  
115     var trajectory = [];
116 	
117 	this.clearTrajectory = function()
118 	{
119 		trajectory = [];
120 	};
121 	
122 	    function getF(C , x0, y0 , x, y  )
123     {
124     	var R = Math.sqrt( (x-x0)*(x-x0)+(y-y0)*(y-y0) ); 
125     	var dx = (1 - R0/R) * (x0-x); 
126     	var dy = (1 - R0/R) * (y0-y); 
127     	
128     	return {x: C*dx, y:C*dy};
129     }
130             
131     function dynamics(){                                    // интегрирование по времени
132         if (!count) return;
133 		if(check.checked){
134 			ellipse.fill = "rgba(0, 0, 255, 1)"
135 		for (var s=1; s<=spf; s++) {
136         	
137 				var f1 = getF(Cx, 0, y0, ellipse.x, ellipse.y);
138 				var f2 = getF(Cx, ocanvas.width, y0, ellipse.x, ellipse.y);
139         	
140 				var f3 = getF(Cy, x0, 0, ellipse.x, ellipse.y);
141 				var f4 = getF(Cy, x0, ocanvas.height, ellipse.x, ellipse.y);
142         	
143 				var fx =  f1.x + f2.x + f3.x + f4.x - B * vx;
144 				var fy =  f1.y + f2.y + f3.y + f4.y - B * vy;
145             
146 				vx += fx / m * dt;
147 				vy += fy / m * dt;
148             
149 				ellipse.x += vx * dt;
150 				ellipse.y += vy * dt;
151 				ellipse.radius = 5 * m;
152 
153 				steps++;
154               
155 				if (steps % 10 == 0) 
156 				{
157 					trajectory.push([ellipse.x - x0, y0 - ellipse.y]);
158 					$.plot($('#vGraph'), [trajectory], {});
159 				} 
160             
161 				drawSpring();
162 				}
163 		}
164 		else {
165 			ellipse.fill = "rgba(255, 0, 0, 1)"
166 			for (var s=1; s<=spf; s++) {
167 		
168 				var fx =  - 2 * Cx * (ellipse.x - x0) - B * vx;
169 				var fy =  - 2 * Cy * (ellipse.y - y0) - B * vy;
170 				vx += fx / m * dt;
171 				vy += fy / m * dt;
172             
173 				ellipse.x += vx * dt;
174 				ellipse.y += vy * dt;
175 				ellipse.radius = 5 * m;
176  
177 				steps++;
178               // подать данные на график
179 				if (steps % 10 == 0) 
180 				{
181 					trajectory.push([ellipse.x-x0, y0-ellipse.y]);
182 					$.plot($('#vGraph'), [trajectory], {});
183 				} 
184             
185 				drawSpring();
186 			}
187         }
188 	}
189  
190     // Рисуем пружины
191 function drawSpring() {
192         for (var i = 0; i < coil; i++ ) {
193         	
194             lines1[i].start.x =  startX1 + ((ellipse.x-startX1) )/coil*i;
195             lines1[i].end.x =    startX1 + ((ellipse.x-startX1))/coil*(i+1);            
196             lines1[i].start.y =  y0 + ((i%2==0)?1:-1)*7 + (ellipse.y-startY1)/coil*i;
197             lines1[i].end.y =    y0 + ((i%2==0)?-1:1)*7 + (ellipse.y-startY1)/coil*(i+1);            
198             if (i==0) lines1[i].start.y =  y0;
199             if (i==(coil-1)) lines1[i].end.y =  ellipse.y;
200             
201             
202             lines2[i].start.x =  startX2 + ((ellipse.x-startX2) )/coil*i;
203             lines2[i].end.x =    startX2 + ((ellipse.x-startX2) )/coil*(i+1);
204             lines2[i].start.y =  y0 + ((i%2==0)?-1:1)*7 + (ellipse.y-startY1)/coil*i;
205             lines2[i].end.y =    y0 + ((i%2==0)?1:-1)*7  + (ellipse.y-startY1)/coil*(i+1);
206             if (i==0) lines2[i].start.y =  y0;
207             if (i==(coil-1)) lines2[i].end.y =  ellipse.y;
208             
209             
210             lines3[i].start.y =  startY3 + ((ellipse.y-startY3) )/coil*i;
211             lines3[i].end.y =    startY3 + ((ellipse.y-startY3))/coil*(i+1);    
212                     
213             lines3[i].start.x =  x0 + ((i%2==0)?-1:1)*7 + (ellipse.x-startX3)/coil*i;
214             lines3[i].end.x =    x0 + ((i%2==0)?1:-1)*7 + (ellipse.x-startX3)/coil*(i+1);            
215             if (i==0) lines3[i].start.x =  x0;
216             if (i==(coil-1)) lines3[i].end.x =  ellipse.x;
217             
218     
219             lines4[i].start.y =  startY4 + ((ellipse.y-startY4) )/coil*i;
220             lines4[i].end.y =    startY4 + ((ellipse.y-startY4) )/coil*(i+1);
221             lines4[i].start.x =  x0 + ((i%2==0)?1:-1)*7 + (ellipse.x-startX4)/coil*i;
222             lines4[i].end.x =    x0 + ((i%2==0)?-1:1)*7  + (ellipse.x-startX4)/coil*(i+1);
223             if (i==0) lines4[i].start.x =  x0;
224             if (i==(coil-1)) lines4[i].end.x =  ellipse.x; 
225         }
226     }
227  
228     ocanvas.setLoop(dynamics).start();             // функция, выполняющаяся на каждом шаге
229 }

Файл "osc.html"

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 	<meta charset="utf-8">
 5     <title>Пружинка</title>
 6     <script src="ocanvas.min.js"></script>
 7     <script src="script.js?<?= time() ?>"></script>
 8     <script src="jquery-1.6.1.min.js"></script>
 9     <script src="TM.js"></script>
10     <script language="javascript" type="text/javascript" src="flot/jquery.flot.js"></script>
11     <script language="javascript" type="text/javascript" src="jquery.flot.axislabels.js"></script>
12 
13 </head>
14 <body>
15     <div style="float:left; width: 607px">
16         <canvas id="canvasMech" width="600" height="600" style="border:1px solid #000000; float: left;"></canvas> 
17     </div>
18  
19     <!--график-->
20     <div id="vGraph" style="width:600px; height:600px; border: 1px solid black; margin-left: 700px "></div>
21     
22     
23     <!--слайдеры-->
24     <div  style="margin-left:20px; margin-top:20px; margin-bottom:20px;">
25         <div> <input type="range" id="slider_m" style="width: 150px;" oninput="app.setSlider_m(this.value); document.getElementById('text_m').value = this.value;">
26         m =
27         <input id="text_m" style="width: 5ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
28             // если введено не число - строка не пройдет валидацию по паттерну выше, и checkValidity() вернет false
29             if (!this.checkValidity()) return;
30             app.setSlider_m(this.value);
31             document.getElementById('slider_m').value = this.value;">
32             </div>
33     <br>
34             <div> <input type="range" id="slider_Cx" style="width: 150px;" oninput="app.setSlider_Cx(this.value); document.getElementById('text_Cx').value = this.value;">
35         Cx =
36         <input id="text_Cx" style="width: 5ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
37             // если введено не число - строка не пройдет валидацию по паттерну выше, и checkValidity() вернет false
38             if (!this.checkValidity()) return;
39             app.setSlider_Cx(this.value);
40             document.getElementById('slider_Cx').value = this.value;">
41             <input type="button" style="width: 100px; margin-left:100px" name="" onclick="app.clearTrajectory();" value="Очистить">
42             </div>
43     <br>
44                 <div> <input type="range" id="slider_Cy" style="width: 150px;" oninput="app.setSlider_Cy(this.value); document.getElementById('text_Cy').value = this.value;">
45         Cy =
46         <input id="text_Cy" style="width: 5ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
47             // если введено не число - строка не пройдет валидацию по паттерну выше, и checkValidity() вернет false
48             if (!this.checkValidity()) return;
49             app.setSlider_Cy(this.value);
50             document.getElementById('slider_Cy').value = this.value;">
51             <input type ="checkbox" id ="check" style="margin-left:100px;" value="0">Сложное движение
52             </div>
53     <br>
54                 <div> <input type="range" id="slider_B" style="width: 150px;" oninput="app.setSlider_B(this.value); document.getElementById('text_B').value = this.value;">
55         B =
56         <input id="text_B" style="width: 5ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
57             // если введено не число - строка не пройдет валидацию по паттерну выше, и checkValidity() вернет false
58             if (!this.checkValidity()) return;
59             app.setSlider_B(this.value);
60             document.getElementById('slider_B').value = this.value;">
61             </div>
62     </div>
63 	    <script type="text/javascript">
64 	var app = new MainMech(
65 		document.getElementById('canvasMech'),
66 		document.getElementById('slider_m'),
67 		document.getElementById('text_m'),
68 		document.getElementById('slider_Cx'),
69 		document.getElementById('text_Cx'),
70 		document.getElementById('slider_Cy'),
71 		document.getElementById('text_Cy'),
72 		document.getElementById('slider_B'),
73 		document.getElementById('text_B'),
74 		document.getElementById('check'));
75 	</script>
76 
77 </body>
78 </html>

</toggledisplay>

Spring.rar - исходные файлы

См. также[править]