Difference between revisions of "Interactive harmonic oscillator model"
From Department of Theoretical and Applied Mechanics
(Created page with "Virtual laboratory > Interactive harmonic oscillator model <HR> Left mouse button on the sinker- drag and drop. {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tc...") |
|||
Line 15: | Line 15: | ||
var canvas = spring_canvas; | var canvas = spring_canvas; | ||
− | canvas.onselectstart = function () {return false;}; // | + | canvas.onselectstart = function () {return false;}; // prohibition selection canvas |
− | var ctx = canvas.getContext("2d"); // | + | var ctx = canvas.getContext("2d"); // Drawing takes place in the ctx |
− | var w = canvas.width; // | + | var w = canvas.width; // the width of the window in the estimated coordinates |
− | var h = canvas.height; // | + | var h = canvas.height; // the height of the window in the estimated coordinates |
− | var Pi = 3.1415926; // | + | var Pi = 3.1415926; // the number "PI" |
− | var m0 = 1; // | + | var m0 = 1; // weight scale |
− | var T0 = 1; // | + | var T0 = 1; // the time scale |
var k0 = 2 * Pi / T0; // масштаб частоты | var k0 = 2 * Pi / T0; // масштаб частоты | ||
Line 31: | Line 31: | ||
// *** Задание физических параметров *** | // *** Задание физических параметров *** | ||
− | var m = 1 * m0; // | + | var m = 1 * m0; // weight |
− | var C = 1 * C0; // | + | var C = 1 * C0; // stiffness |
− | var B = .1 * B0; // | + | var B = .1 * B0; // viscosity |
slider_m.value = (m / m0).toFixed(1); number_m.value = (m / m0).toFixed(1); | slider_m.value = (m / m0).toFixed(1); number_m.value = (m / m0).toFixed(1); | ||
slider_C.value = (C / C0).toFixed(1); number_C.value = (C / C0).toFixed(1); | slider_C.value = (C / C0).toFixed(1); number_C.value = (C / C0).toFixed(1); | ||
Line 40: | Line 40: | ||
// *** Задание вычислительных параметров *** | // *** Задание вычислительных параметров *** | ||
− | var fps = 60; // frames per second - | + | var fps = 60; // frames per second - the number of frames per second |
− | var spf = 10; // steps per frame - | + | var spf = 10; // steps per frame - the number of integration steps between frames (edtkbxbdftn скорость расчета) |
− | var dt = 0.05 * T0 / fps; // | + | var dt = 0.05 * T0 / fps; // the step of integration |
− | var steps = 0; // | + | var steps = 0; // the number of integration steps |
− | |||
function setM(new_m) {m = new_m * m0;} | function setM(new_m) {m = new_m * m0;} | ||
function setC(new_C) {C = new_C * C0;} | function setC(new_C) {C = new_C * C0;} | ||
Line 56: | Line 55: | ||
number_B.oninput = function() {slider_B.value = number_B.value; setB(number_B.value);}; | number_B.oninput = function() {slider_B.value = number_B.value; setB(number_B.value);}; | ||
− | var count = true; // | + | var count = true; // whether or not the calculation of a system |
− | var v = 0; // | + | var v = 0; // the speed of the body |
var rw = canvas.width / 30; var rh = canvas.height / 1.5; | var rw = canvas.width / 30; var rh = canvas.height / 1.5; | ||
var x0 = 15 * rw - rw / 2; var y0 = rh / 1.33 - rh / 2; | var x0 = 15 * rw - rw / 2; var y0 = rh / 1.33 - rh / 2; | ||
− | // | + | // the parameters of the spring |
− | var coil = 10; // | + | var coil = 10; // the number of turns |
− | var startX = 0; // | + | var startX = 0; // fixing springs |
− | // | + | // create a rectangle |
var rect = { | var rect = { | ||
x: x0, width: rw, | x: x0, width: rw, | ||
y: y0, height: rh, | y: y0, height: rh, | ||
− | fill: "rgba(0, 0, 255, 1)" // | + | fill: "rgba(0, 0, 255, 1)" // color |
+ | |||
}; | }; | ||
− | // | + | // capture the rectangle with the mouse |
− | var mx_; // | + | var mx_; // the buffer position of the mouse |
− | document.onmousedown = function(e) { // | + | document.onmousedown = function(e) { // function by pressing the mouse button |
− | var m = mouseCoords(e); // | + | var m = mouseCoords(e); // received the estimated coordinates of the mouse cursor |
var x = rect.x; | var x = rect.x; | ||
Line 83: | Line 83: | ||
var yh = rect.y + rect.height; | var yh = rect.y + rect.height; | ||
if (x <= m.x && xw >= m.x && y <= m.y && yh >= m.y) { | if (x <= m.x && xw >= m.x && y <= m.y && yh >= m.y) { | ||
− | if (e.which == 1) { // | + | if (e.which == 1) { // Left mouse button is pressed |
− | rect.xPlus = rect.x - m.x; // | + | rect.xPlus = rect.x - m.x; // cursor shift relative to the sinker on the x |
− | rect.yPlus = rect.y - m.y; // | + | rect.yPlus = rect.y - m.y; // cursor shift relative to the sinker on the y |
mx_ = m.x; | mx_ = m.x; | ||
count = false; | count = false; | ||
− | document.onmousemove = mouseMove; // | + | document.onmousemove = mouseMove; // until a key is pressed - is working on the movement |
} | } | ||
} | } | ||
}; | }; | ||
− | document.onmouseup = function(e) { // | + | document.onmouseup = function(e) { // function when you release the mouse button |
− | document.onmousemove = null; // | + | document.onmousemove = null; // when the key is released - no movement function |
count = true; | count = true; | ||
}; | }; | ||
− | function mouseMove(e) { // | + | function mouseMove(e) { // function when you move the mouse , it works only with the left mouse button |
− | var m = mouseCoords(e); // | + | var m = mouseCoords(e); // received the estimated coordinates of the mouse cursor |
rect.x = m.x + rect.xPlus; | rect.x = m.x + rect.xPlus; | ||
− | // v = 6.0 * (m.x - mx_) / dt / fps; // | + | // v = 6.0 * (m.x - mx_) / dt / fps; // the preservation of inertia |
v = 0; | v = 0; | ||
mx_ = m.x; | mx_ = m.x; | ||
} | } | ||
− | function mouseCoords(e) { // | + | function mouseCoords(e) { // the function returns the calculated coordinates of the mouse cursor |
var m = []; | var m = []; | ||
var rect = canvas.getBoundingClientRect(); | var rect = canvas.getBoundingClientRect(); | ||
Line 115: | Line 115: | ||
// график | // график | ||
− | var vGraph = new TM_graph( // | + | var vGraph = new TM_graph( // determine the timetable |
− | "#vGraph", // | + | "#vGraph", // on html- element #vGraph |
− | 250, // | + | 250, // how many steps on the "x" axis shows |
− | -1, 1, 0.2); // | + | -1, 1, 0.2); // min. value of Y -axis , max . value of Y -axis , Y -axis step |
function control() { | function control() { | ||
Line 126: | Line 126: | ||
} | } | ||
control(); | control(); | ||
− | // setInterval(control, 1000 / fps); // | + | // setInterval(control, 1000 / fps); // Starting system |
function calculate() { | function calculate() { | ||
Line 136: | Line 136: | ||
steps++; | steps++; | ||
− | if (steps % 80 == 0) vGraph.graphIter(steps, (rect.x-x0)/canvas.width*2); // | + | if (steps % 80 == 0) vGraph.graphIter(steps, (rect.x-x0)/canvas.width*2); // submit the data on a graph |
} | } | ||
Revision as of 02:59, 4 June 2016
Virtual laboratory > Interactive harmonic oscillator modelLeft mouse button on the sinker- drag and drop.
Download Spring_v2-1_release.zip.
The program text in the language JavaScript (Developers D.V. Tsvetkov, A.M. Krivtsov)
File "Spring.js"
1 window.addEventListener("load", Main_Spring, true);
2 function Main_Spring() {
3
4 var canvas = spring_canvas;
5 canvas.onselectstart = function () {return false;}; // prohibition selection canvas
6 var ctx = canvas.getContext("2d"); // Drawing takes place in the ctx
7 var w = canvas.width; // the width of the window in the estimated coordinates
8 var h = canvas.height; // the height of the window in the estimated coordinates
9
10 var Pi = 3.1415926; // the number "PI"
11
12 var m0 = 1; // weight scale
13 var T0 = 1; // the time scale
14
15 var k0 = 2 * Pi / T0; // масштаб частоты
16 var C0 = m0 * k0 * k0; // масштаб жесткости
17 var B0 = 2 * m0 * k0; // масштаб вязкости
18
19 // *** Задание физических параметров ***
20
21 var m = 1 * m0; // weight
22 var C = 1 * C0; // stiffness
23 var B = .1 * B0; // viscosity
24 slider_m.value = (m / m0).toFixed(1); number_m.value = (m / m0).toFixed(1);
25 slider_C.value = (C / C0).toFixed(1); number_C.value = (C / C0).toFixed(1);
26 slider_B.value = (B / B0).toFixed(1); number_B.value = (B / B0).toFixed(1);
27
28 // *** Задание вычислительных параметров ***
29
30 var fps = 60; // frames per second - the number of frames per second
31 var spf = 10; // steps per frame - the number of integration steps between frames (edtkbxbdftn скорость расчета)
32 var dt = 0.05 * T0 / fps; // the step of integration
33 var steps = 0; // the number of integration steps
34 function setM(new_m) {m = new_m * m0;}
35 function setC(new_C) {C = new_C * C0;}
36 function setB(new_B) {B = new_B * B0;}
37
38 slider_m.oninput = function() {number_m.value = slider_m.value; setM(slider_m.value);};
39 number_m.oninput = function() {slider_m.value = number_m.value; setM(number_m.value);};
40 slider_C.oninput = function() {number_C.value = slider_C.value; setC(slider_C.value);};
41 number_C.oninput = function() {slider_C.value = number_C.value; setC(number_C.value);};
42 slider_B.oninput = function() {number_B.value = slider_B.value; setB(slider_B.value);};
43 number_B.oninput = function() {slider_B.value = number_B.value; setB(number_B.value);};
44
45 var count = true; // whether or not the calculation of a system
46 var v = 0; // the speed of the body
47
48 var rw = canvas.width / 30; var rh = canvas.height / 1.5;
49 var x0 = 15 * rw - rw / 2; var y0 = rh / 1.33 - rh / 2;
50
51 // the parameters of the spring
52 var coil = 10; // the number of turns
53 var startX = 0; // fixing springs
54
55 // create a rectangle
56 var rect = {
57 x: x0, width: rw,
58 y: y0, height: rh,
59 fill: "rgba(0, 0, 255, 1)" // color
60
61 };
62
63 // capture the rectangle with the mouse
64 var mx_; // the buffer position of the mouse
65 document.onmousedown = function(e) { // function by pressing the mouse button
66 var m = mouseCoords(e); // received the estimated coordinates of the mouse cursor
67
68 var x = rect.x;
69 var xw = rect.x + rect.width;
70 var y = rect.y;
71 var yh = rect.y + rect.height;
72 if (x <= m.x && xw >= m.x && y <= m.y && yh >= m.y) {
73 if (e.which == 1) { // Left mouse button is pressed
74 rect.xPlus = rect.x - m.x; // cursor shift relative to the sinker on the x
75 rect.yPlus = rect.y - m.y; // cursor shift relative to the sinker on the y
76 mx_ = m.x;
77 count = false;
78 document.onmousemove = mouseMove; // until a key is pressed - is working on the movement
79 }
80 }
81 };
82
83 document.onmouseup = function(e) { // function when you release the mouse button
84 document.onmousemove = null; // when the key is released - no movement function
85 count = true;
86 };
87
88 function mouseMove(e) { // function when you move the mouse , it works only with the left mouse button
89 var m = mouseCoords(e); // received the estimated coordinates of the mouse cursor
90 rect.x = m.x + rect.xPlus;
91 // v = 6.0 * (m.x - mx_) / dt / fps; // the preservation of inertia
92 v = 0;
93 mx_ = m.x;
94 }
95
96 function mouseCoords(e) { // the function returns the calculated coordinates of the mouse cursor
97 var m = [];
98 var rect = canvas.getBoundingClientRect();
99 m.x = (e.clientX - rect.left);
100 m.y = (e.clientY - rect.top);
101 return m;
102 }
103
104 // график
105 var vGraph = new TM_graph( // determine the timetable
106 "#vGraph", // on html- element #vGraph
107 250, // how many steps on the "x" axis shows
108 -1, 1, 0.2); // min. value of Y -axis , max . value of Y -axis , Y -axis step
109
110 function control() {
111 calculate();
112 draw();
113 requestAnimationFrame(control);
114 }
115 control();
116 // setInterval(control, 1000 / fps); // Starting system
117
118 function calculate() {
119 if (!count) return;
120 for (var s=1; s<=spf; s++) {
121 var f = - C * (rect.x - x0) - B * v;
122 v += f / m * dt;
123 rect.x += v * dt;
124
125 steps++;
126 if (steps % 80 == 0) vGraph.graphIter(steps, (rect.x-x0)/canvas.width*2); // submit the data on a graph
127 }
128
129 }
130
131 function draw() {
132 ctx.clearRect(0, 0, w, h);
133
134 ctx.strokeStyle = "#0aa";
135 ctx.beginPath();
136 ctx.moveTo(0, y0+rh/2);
137 for (var i = 1; i <= coil + 1; i++ ) {
138 var x;
139 var y;
140 if (i != coil + 1) {
141 x = startX + ((rect.x - startX))/coil*i - ((rect.x - startX))/coil/2;
142 y = y0+rh/2 + ((i%2==0)?1:-1)*30;
143 } else {
144 x = startX + ((rect.x - startX))/coil*i - ((rect.x - startX))/coil;
145 y = y0+rh/2;
146 }
147
148 ctx.lineTo(x, y);
149 }
150 ctx.stroke();
151
152 ctx.fillStyle = "#0000ff";
153 ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
154 }
155 }
Файл "Spring.html"
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8" />
5 <title>Пружина</title>
6 <script src="Spring.js"></script>
7 <script src="jquery.min.js"></script>
8 <script src="jquery.flot.js"></script>
9 <script src="TM_v2-1.js"></script>
10 </head>
11 <body>
12 <canvas id="spring_canvas" width="600" height="100" style="border:1px solid #000000;"></canvas><br>
13 <input type="range" id="slider_m" min="0.01" max="10" step=0.01 style="width: 150px;" />
14 m = <input type="number" id="number_m" min="0.01" max="10" step=0.01 style="width: 50px;" /><br>
15 <input type="range" id="slider_C" min="0" max="10" step=0.01 style="width: 150px;" />
16 C = <input type="number" id="number_C" min="0" max="10" step=0.01 style="width: 50px;" /><br>
17 <input type="range" id="slider_B" min="0" max="10" step=0.01 style="width: 150px;" />
18 B = <input type="number" id="number_B" min="0" max="10" step=0.01 style="width: 50px;" /><br><br>
19
20 <table>
21 <tr><td>x</td>
22 <td><div id="vGraph" style="width:600px; height:300px; clear:both;"></div></td>
23 </tr>
24 <tr><td></td><td style="text-align: center">steps</td></tr>
25 </table>
26 </body>
27 </html>