КП: Моделирование пружин
Материал из 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 - исходные файлы