Колебания с двумя степенями свободы — различия между версиями
Материал из Department of Theoretical and Applied Mechanics
Строка 20: | Строка 20: | ||
<div class="mw-collapsible mw-collapsed" style="width:100%" > | <div class="mw-collapsible mw-collapsed" style="width:100%" > | ||
− | '''Текст программы на языке JavaScript (разработчик [[ | + | '''Текст программы на языке JavaScript (разработчик [[Погодина Валерия]], код основан на программе [[Цветков Денис]]):''' <div class="mw-collapsible-content"> |
− | Файл '''" | + | Файл '''"Balls_v1_release.js"''' |
<syntaxhighlight lang="javascript" line start="1" enclose="div"> | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
− | + | function MainBalls(canvasBalls, canvasBalls1, canvasBalls2) { | |
− | + | ||
− | + | // Предварительные установки | |
− | var | + | |
− | + | var context = canvasBalls.getContext("2d"); // на context происходит рисование | |
− | + | var context1 = canvasBalls1.getContext("2d"); // на context1 происходит рисование | |
− | + | var context2 = canvasBalls2.getContext("2d"); // на context2 происходит рисование | |
− | + | var c1 = 5; | |
− | + | var Pi = 3.1415926; // число "пи" | |
− | + | var a0 = 1; // масштаб расстояния (диаметр шара) | |
− | + | var T0 = 1; // масштаб времени (период колебаний исходной системы) | |
− | var | + | var m0 = 1; // масштаб массы |
− | + | var g0 = a0 / T0 / T0; // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0) | |
− | + | var k0 = 2 * Pi / T0; // масштаб частоты | |
− | + | var C0 = m0 * k0 * k0; // масштаб жесткости | |
− | + | ||
− | + | ||
− | var | ||
− | |||
− | |||
// *** Задание физических параметров *** | // *** Задание физических параметров *** | ||
− | var | + | |
− | var | + | var Ny = 5; // число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна) |
− | + | var r = 0.5 * a0; // радиус частицы в расчетных координатах | |
− | + | var m = 1 * m0; // масса | |
− | var | + | var g = 0.25 * g0; // ускорение свободного падения |
− | var | + | var c = c1 * C0; // жесткость пружины |
− | + | var l0 = 6 * a0; // длина пружины | |
− | + | var L = l0 + m * g / c; // длина пружины под воздействием силы тяжести | |
− | + | var time = 0; | |
− | |||
− | |||
− | |||
− | |||
− | var fps = 100; | + | Text_c.value = c1; |
− | var spf = | + | Text_m.value = m; |
− | var dt = 0. | + | |
− | + | Slider_c.min = 1; | |
+ | Slider_c.max = 10; | ||
+ | Slider_c.step = 0.5; | ||
+ | Slider_c.value = Text_c.value; | ||
+ | |||
+ | Slider_m.min = 1; | ||
+ | Slider_m.max = 3; | ||
+ | Slider_m.step = 0.1; | ||
+ | Slider_m.value = Text_m.value; | ||
+ | |||
+ | // *** Задание вычислительных параметров *** | ||
+ | |||
+ | var fps = 100; // frames per second - число кадров в секунду (качечтво отображения) | ||
+ | var spf = 100; // steps per frame - число шагов интегрирования между кадрами (скорость расчета) | ||
+ | var dt = 0.045 * T0 / fps; // шаг интегрирования (качество расчета) | ||
− | + | // Выполнение программы | |
− | + | ||
− | + | var scale = canvasBalls.height / Ny / a0; // масштабный коэффициент для перехода от расчетных к экранным координатам | |
− | + | var w = canvasBalls.width / scale; // ширина окна в расчетных координатах | |
− | + | var h = canvasBalls.height / scale; // высота окна в расчетных координатах | |
− | + | ||
+ | // Добавление шара | ||
+ | |||
+ | var b = []; | ||
+ | b.x = w / 2; b.y = h * 0.7; // расчетные координаты шара | ||
+ | b.vx = 0.5; b.vy = 0.5; // начальная скорость | ||
+ | |||
− | + | setInterval(control1, 1000 / fps); | |
− | + | ||
− | + | function control1() { | |
− | + | physics1(); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
draw(); | draw(); | ||
− | |||
} | } | ||
− | |||
− | |||
+ | function physics1() { // то, что происходит каждый шаг времени | ||
+ | for (var s = 1; s <= spf; s++) { | ||
+ | b.vx += -g / L * (b.x - w/2) * dt; b.vy += -c / m * (b.y - h * 0.7) * dt; | ||
+ | b.x += b.vx * dt; b.y += b.vy * dt; | ||
+ | } | ||
+ | } | ||
− | + | /* function physics2() { // то, что происходит каждый шаг времени | |
− | + | for (var s = 1; s <= spf; s++) { | |
− | for (var s=1; s<=spf; s++) { | + | |
− | + | b.vx += -c * (Math.sqrt(Math.pow((L + b.y - h * 0.7),2) + Math.pow((b.x - w/2), 2) - l0)) * (b.x - w/2) / (Math.sqrt(Math.pow((L + b.y - h * 0.7),2) + Math.pow((b.x - w/2),2))) / m * dt; | |
− | + | b.vy += -c * (Math.sqrt(Math.pow((L + b.y - h * 0.7),2) + Math.pow((b.x - w/2), 2) - l0)) * (L + b.y - h * 0.7) / (Math.sqrt(Math.pow((L + b.y - h * 0.7),2) + Math.pow((b.x - w/2),2))) / m * dt; | |
− | + | b.x += b.vx * dt; b.y += b.vy * dt; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | |||
} | } | ||
− | function | + | */ |
− | + | this.set_m = function(input) | |
− | + | { | |
− | + | m = Number(input); | |
− | + | time = 0; | |
− | + | b.x = w / 2; b.y = h * 0.7; | |
− | + | b.vx = 0.5; b.vy = 0.5; | |
− | + | context.clearRect(0, 0, w * scale, h * scale); | |
− | + | context1.clearRect(0, 0, w * scale, h * scale); | |
− | + | context2.clearRect(0, 0, w * scale, h * scale); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | ||
− | + | ||
− | + | this.set_c = function(input) | |
− | + | { | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | c1 = Number(input); | |
− | + | time = 0; | |
− | + | b.x = w / 2; b.y = h * 0.7; | |
− | + | b.vx = 0.5; b.vy = 0.5; | |
− | + | context.clearRect(0, 0, w * scale, h* scale); | |
− | + | context1.clearRect(0, 0, w * scale, h * scale); | |
− | + | context2.clearRect(0, 0, w * scale, h * scale); | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | } | ||
− | + | function draw() { | |
− | + | context.fillStyle = "#ff0000"; | |
− | function | + | context.clearRect(0, 0, w * scale, h * scale); // очистить экран |
− | + | context.beginPath(); | |
− | + | conte xt.arc(b.x * scale, b.y * scale, r * scale / 3, 0, 2 * Math.PI, false); //рисуем шар | |
− | + | context.fill(); | |
− | + | context.closePath(); | |
− | + | context.lineWidth="6"; | |
− | + | context.strokeStyle="#990099"; | |
− | + | context.beginPath(); //рисуем пружину | |
− | + | context.moveTo(w/ 2 * scale, 0); | |
− | + | context.lineTo(b.x * scale, b.y * scale); | |
− | + | context.stroke(); | |
− | + | ||
− | + | context1.strokeStyle = "red"; //рисуем график 1 | |
− | + | context1.beginPath(); | |
− | + | context1.moveTo(time * Math.sqrt(c / m) / 20 * scale, (b.x - h / 6) * scale); | |
− | + | context1.lineTo((time + dt) * Math.sqrt(c / m) / 20 * scale, (b.x - h / 6) * scale); | |
− | + | context1.stroke(); | |
− | + | ||
− | + | context1.strokeStyle="#000000"; //рисуем систему координат на 1 графике | |
− | + | context1.beginPath(); | |
− | + | context1.moveTo(0, h / 2 * scale); | |
− | + | context1.lineTo(w * scale, h / 2 * scale); | |
− | + | context1.stroke(); | |
− | + | context1.strokeStyle="#000000"; | |
− | + | context1.beginPath(); | |
− | + | context1.moveTo(w / 2 * scale , 0); | |
− | + | context1.lineTo(w / 2 * scale, h * scale); | |
− | + | context1.stroke(); | |
− | + | ||
− | } | + | context2.strokeStyle = "#3070d0"; //рисуем график 2 |
+ | context2.beginPath(); | ||
+ | context2.moveTo(time * Math.sqrt(c / m) * scale, (b.y - h / 5) * scale); | ||
+ | context2.lineTo((time + dt) * Math.sqrt(c / m) * scale, (b.y - h / 5) * scale); | ||
+ | context2.stroke(); | ||
+ | |||
+ | context2.strokeStyle="#000000"; //рисуем систему координат на графике 2 | ||
+ | context2.beginPath(); | ||
+ | context2.moveTo(0, h / 2 * scale); | ||
+ | context2.lineTo(w * scale, h / 2 * scale); | ||
+ | context2.stroke(); | ||
+ | context2.strokeStyle="#000000"; | ||
+ | context2.beginPath(); | ||
+ | context2.moveTo(w / 2 * scale , 0); | ||
+ | context2.lineTo(w / 2 * scale, h * scale); | ||
+ | context2.stroke(); | ||
+ | |||
+ | time += dt; | ||
+ | } | ||
+ | |||
+ | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Файл '''" | + | Файл '''"new1.html"''' |
<syntaxhighlight lang="html5" line start="1" enclose="div"> | <syntaxhighlight lang="html5" line start="1" enclose="div"> | ||
<!DOCTYPE html> | <!DOCTYPE html> | ||
<html> | <html> | ||
<head> | <head> | ||
− | <meta charset="UTF-8" /> | + | <meta charset="UTF-8"/> |
− | <title> | + | <title> Balls </title> |
− | <script src=" | + | <script src="Balls_v1_release.js"></script> |
− | |||
− | |||
</head> | </head> | ||
<body> | <body> | ||
− | + | <canvas id="canvasBalls" width="800" height="600" style="border:1px solid #000000;"></canvas> | |
− | + | <div> | |
− | + | <!-- Масса--> | |
− | + | <div> | |
− | < | + | m = |
− | + | <input id="Text_m" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput=" | |
− | + | if (!this.checkValidity()) return; | |
− | + | app.set_m(this.value); | |
− | + | document.getElementById('Slider_m').value = this.value; | |
− | + | "> | |
− | + | <input type = "range" id="Slider_m" style="width: 100px;" oninput="app.set_m(this.value); document.getElementById('Text_m').value = this.value;"> | |
− | + | </I></font> | |
− | + | </div> | |
− | + | <!-- Жесткость--> | |
− | + | <div> | |
− | + | c = | |
− | + | <input id="Text_c" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput=" | |
− | + | if (!this.checkValidity()) return; | |
− | + | app.set_c(this.value); | |
− | + | document.getElementById('Slider_c').value = this.value; | |
− | + | "> | |
− | + | <input type = "range" id="Slider_c" style="width: 100px;" oninput="app.set_c(this.value); document.getElementById('Text_c').value = this.value;"> | |
− | + | </I></font> | |
− | + | </div> | |
+ | <b>Зависимость координаты х от k1*t:</b> | ||
+ | </div> | ||
+ | <canvas id="canvasBalls1" width="800" height="600" style="border:1px solid #000000;"></canvas> | ||
+ | <div> | ||
+ | <b>Зависимость координаты y от k1*t:</b> | ||
+ | </div> | ||
+ | <canvas id="canvasBalls2" width="800" height="600" style="border:1px solid #000000;"></canvas> | ||
+ | <script type="text/javascript"> app = new MainBalls(document.getElementById('canvasBalls'),document.getElementById('canvasBalls1'),document.getElementById('canvasBalls2'));</script> | ||
</body> | </body> | ||
</html> | </html> |
Версия 12:21, 27 мая 2015
Виртуальная лаборатория>Колебания с двумя степенями свободыМаятник с двумя степенями свободы
Тяжелая материальная точка массы
подвешена на невесомой пружине жесткости и длины в ненапряженном состоянии.
Уравнения движения системы будут выглядеть так:
, где
Колебания выглядят так:
Скачать Shock_absorbers.zip.
Текст программы на языке JavaScript (разработчик Погодина Валерия, код основан на программе Цветков Денис):
Файл "Balls_v1_release.js"
1 function MainBalls(canvasBalls, canvasBalls1, canvasBalls2) {
2
3 // Предварительные установки
4
5 var context = canvasBalls.getContext("2d"); // на context происходит рисование
6 var context1 = canvasBalls1.getContext("2d"); // на context1 происходит рисование
7 var context2 = canvasBalls2.getContext("2d"); // на context2 происходит рисование
8 var c1 = 5;
9 var Pi = 3.1415926; // число "пи"
10 var a0 = 1; // масштаб расстояния (диаметр шара)
11 var T0 = 1; // масштаб времени (период колебаний исходной системы)
12 var m0 = 1; // масштаб массы
13 var g0 = a0 / T0 / T0; // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
14 var k0 = 2 * Pi / T0; // масштаб частоты
15 var C0 = m0 * k0 * k0; // масштаб жесткости
16
17
18 // *** Задание физических параметров ***
19
20 var Ny = 5; // число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
21 var r = 0.5 * a0; // радиус частицы в расчетных координатах
22 var m = 1 * m0; // масса
23 var g = 0.25 * g0; // ускорение свободного падения
24 var c = c1 * C0; // жесткость пружины
25 var l0 = 6 * a0; // длина пружины
26 var L = l0 + m * g / c; // длина пружины под воздействием силы тяжести
27 var time = 0;
28
29
30 Text_c.value = c1;
31 Text_m.value = m;
32
33 Slider_c.min = 1;
34 Slider_c.max = 10;
35 Slider_c.step = 0.5;
36 Slider_c.value = Text_c.value;
37
38 Slider_m.min = 1;
39 Slider_m.max = 3;
40 Slider_m.step = 0.1;
41 Slider_m.value = Text_m.value;
42
43 // *** Задание вычислительных параметров ***
44
45 var fps = 100; // frames per second - число кадров в секунду (качечтво отображения)
46 var spf = 100; // steps per frame - число шагов интегрирования между кадрами (скорость расчета)
47 var dt = 0.045 * T0 / fps; // шаг интегрирования (качество расчета)
48
49 // Выполнение программы
50
51 var scale = canvasBalls.height / Ny / a0; // масштабный коэффициент для перехода от расчетных к экранным координатам
52 var w = canvasBalls.width / scale; // ширина окна в расчетных координатах
53 var h = canvasBalls.height / scale; // высота окна в расчетных координатах
54
55 // Добавление шара
56
57 var b = [];
58 b.x = w / 2; b.y = h * 0.7; // расчетные координаты шара
59 b.vx = 0.5; b.vy = 0.5; // начальная скорость
60
61
62 setInterval(control1, 1000 / fps);
63
64 function control1() {
65 physics1();
66 draw();
67 }
68
69 function physics1() { // то, что происходит каждый шаг времени
70 for (var s = 1; s <= spf; s++) {
71 b.vx += -g / L * (b.x - w/2) * dt; b.vy += -c / m * (b.y - h * 0.7) * dt;
72 b.x += b.vx * dt; b.y += b.vy * dt;
73 }
74 }
75
76 /* function physics2() { // то, что происходит каждый шаг времени
77 for (var s = 1; s <= spf; s++) {
78
79 b.vx += -c * (Math.sqrt(Math.pow((L + b.y - h * 0.7),2) + Math.pow((b.x - w/2), 2) - l0)) * (b.x - w/2) / (Math.sqrt(Math.pow((L + b.y - h * 0.7),2) + Math.pow((b.x - w/2),2))) / m * dt;
80 b.vy += -c * (Math.sqrt(Math.pow((L + b.y - h * 0.7),2) + Math.pow((b.x - w/2), 2) - l0)) * (L + b.y - h * 0.7) / (Math.sqrt(Math.pow((L + b.y - h * 0.7),2) + Math.pow((b.x - w/2),2))) / m * dt;
81 b.x += b.vx * dt; b.y += b.vy * dt;
82 }
83 }
84 */
85 this.set_m = function(input)
86 {
87 m = Number(input);
88 time = 0;
89 b.x = w / 2; b.y = h * 0.7;
90 b.vx = 0.5; b.vy = 0.5;
91 context.clearRect(0, 0, w * scale, h * scale);
92 context1.clearRect(0, 0, w * scale, h * scale);
93 context2.clearRect(0, 0, w * scale, h * scale);
94 }
95
96
97 this.set_c = function(input)
98 {
99
100 c1 = Number(input);
101 time = 0;
102 b.x = w / 2; b.y = h * 0.7;
103 b.vx = 0.5; b.vy = 0.5;
104 context.clearRect(0, 0, w * scale, h* scale);
105 context1.clearRect(0, 0, w * scale, h * scale);
106 context2.clearRect(0, 0, w * scale, h * scale);
107 }
108
109 function draw() {
110 context.fillStyle = "#ff0000";
111 context.clearRect(0, 0, w * scale, h * scale); // очистить экран
112 context.beginPath();
113 conte xt.arc(b.x * scale, b.y * scale, r * scale / 3, 0, 2 * Math.PI, false); //рисуем шар
114 context.fill();
115 context.closePath();
116 context.lineWidth="6";
117 context.strokeStyle="#990099";
118 context.beginPath(); //рисуем пружину
119 context.moveTo(w/ 2 * scale, 0);
120 context.lineTo(b.x * scale, b.y * scale);
121 context.stroke();
122
123 context1.strokeStyle = "red"; //рисуем график 1
124 context1.beginPath();
125 context1.moveTo(time * Math.sqrt(c / m) / 20 * scale, (b.x - h / 6) * scale);
126 context1.lineTo((time + dt) * Math.sqrt(c / m) / 20 * scale, (b.x - h / 6) * scale);
127 context1.stroke();
128
129 context1.strokeStyle="#000000"; //рисуем систему координат на 1 графике
130 context1.beginPath();
131 context1.moveTo(0, h / 2 * scale);
132 context1.lineTo(w * scale, h / 2 * scale);
133 context1.stroke();
134 context1.strokeStyle="#000000";
135 context1.beginPath();
136 context1.moveTo(w / 2 * scale , 0);
137 context1.lineTo(w / 2 * scale, h * scale);
138 context1.stroke();
139
140 context2.strokeStyle = "#3070d0"; //рисуем график 2
141 context2.beginPath();
142 context2.moveTo(time * Math.sqrt(c / m) * scale, (b.y - h / 5) * scale);
143 context2.lineTo((time + dt) * Math.sqrt(c / m) * scale, (b.y - h / 5) * scale);
144 context2.stroke();
145
146 context2.strokeStyle="#000000"; //рисуем систему координат на графике 2
147 context2.beginPath();
148 context2.moveTo(0, h / 2 * scale);
149 context2.lineTo(w * scale, h / 2 * scale);
150 context2.stroke();
151 context2.strokeStyle="#000000";
152 context2.beginPath();
153 context2.moveTo(w / 2 * scale , 0);
154 context2.lineTo(w / 2 * scale, h * scale);
155 context2.stroke();
156
157 time += dt;
158 }
159
160 }
Файл "new1.html"
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8"/>
5 <title> Balls </title>
6 <script src="Balls_v1_release.js"></script>
7 </head>
8 <body>
9 <canvas id="canvasBalls" width="800" height="600" style="border:1px solid #000000;"></canvas>
10 <div>
11 <!-- Масса-->
12 <div>
13 m =
14 <input id="Text_m" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
15 if (!this.checkValidity()) return;
16 app.set_m(this.value);
17 document.getElementById('Slider_m').value = this.value;
18 ">
19 <input type = "range" id="Slider_m" style="width: 100px;" oninput="app.set_m(this.value); document.getElementById('Text_m').value = this.value;">
20 </I></font>
21 </div>
22 <!-- Жесткость-->
23 <div>
24 c =
25 <input id="Text_c" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
26 if (!this.checkValidity()) return;
27 app.set_c(this.value);
28 document.getElementById('Slider_c').value = this.value;
29 ">
30 <input type = "range" id="Slider_c" style="width: 100px;" oninput="app.set_c(this.value); document.getElementById('Text_c').value = this.value;">
31 </I></font>
32 </div>
33 <b>Зависимость координаты х от k1*t:</b>
34 </div>
35 <canvas id="canvasBalls1" width="800" height="600" style="border:1px solid #000000;"></canvas>
36 <div>
37 <b>Зависимость координаты y от k1*t:</b>
38 </div>
39 <canvas id="canvasBalls2" width="800" height="600" style="border:1px solid #000000;"></canvas>
40 <script type="text/javascript"> app = new MainBalls(document.getElementById('canvasBalls'),document.getElementById('canvasBalls1'),document.getElementById('canvasBalls2'));</script>
41 </body>
42 </html>