Цепочка из частиц с вращательными степенями свободы — различия между версиями
Строка 14: | Строка 14: | ||
window.addEventListener("load", MainSystem, true); | window.addEventListener("load", MainSystem, true); | ||
− | function MainSystem() | + | |
− | { | + | function MainSystem(){ |
− | + | var context_s = canvasSystem.getContext('2d'); | |
− | var context_g = canvasGraph.getContext('2d'); | + | var context_g = canvasGraph.getContext('2d'); |
var context_g_1 = canvasGraph_1.getContext('2d'); | var context_g_1 = canvasGraph_1.getContext('2d'); | ||
var context_g_2 = canvasGraph_2.getContext('2d'); | var context_g_2 = canvasGraph_2.getContext('2d'); | ||
− | + | ||
− | + | const Pi = 3.1415926; | |
− | + | const m0 = 1; | |
− | + | const T0 = 1; | |
const l0 = 1; | const l0 = 1; | ||
const E0 = 1; | const E0 = 1; | ||
− | + | ||
− | // | + | //Width of canvas - width of browser |
− | const distance_between_canvases = 5; | + | const distance_between_canvases = 5; //5px |
canvasSystem.width = document.body.clientWidth; | canvasSystem.width = document.body.clientWidth; | ||
canvasGraph.width = document.body.clientWidth / 2 - distance_between_canvases; | canvasGraph.width = document.body.clientWidth / 2 - distance_between_canvases; | ||
Строка 34: | Строка 34: | ||
canvasGraph_2.width = document.body.clientWidth; | canvasGraph_2.width = document.body.clientWidth; | ||
− | + | /* -- Used constans -- */ | |
− | const l = | + | var Db = 0.1 * l0; // Diameter of beam |
− | const a = 60 * l0; // | + | const l = 30 * l0; //Length of beam |
+ | const a = 60 * l0; //Length of object | ||
var Db2 = Db * Db; | var Db2 = Db * Db; | ||
− | var J = Pi * Db2 * Db2 / 64; | + | var J = Pi * Db2 * Db2 / 64; //Polar moment of inertia |
− | const E = 10000000 * E0; // | + | const E = 10000000 * E0; //Youngs modulus |
var C = E * J / l; | var C = E * J / l; | ||
− | var N = parseFloat(number_of_objects.value) + 1; // | + | var N = parseFloat(number_of_objects.value) + 1; //number_of_objects.value is number of objects |
− | const m = 0.01 * m0; // | + | const m = 0.01 * m0; //Mass of object |
− | + | const Q = m * a * a / 12; //Moment of inertia | |
− | const w_c = Math.sqrt(2 * C / Q); // | + | const w_c = Math.sqrt(2 * C / Q); //Self frequency |
+ | |||
+ | const fps = 50; // frames per second | ||
+ | var spf = calcul_speed.value; // steps per frame | ||
+ | const frequency = 1000 / fps; //frequency of call function - 1000 milliseconds/ fps | ||
+ | const dt = 0.05 * T0 / fps; //Step of integration | ||
+ | |||
+ | var scale = canvasSystem.width / N; //Scale of graph of system | ||
+ | var scale1 = canvasGraph_2.width / (N + 2); //Scale of graph of angels | ||
+ | |||
+ | //For wave | ||
+ | const n = 1; //Number of full-wave | ||
+ | var k_ = 2 * Pi / (l * (N - 2) * n); //Spatial frequencyw | ||
+ | var w_ = Math.sqrt((-2 * C / Q * l * l) * k_ * k_ + (12 * C / Q)); | ||
+ | |||
+ | /* -- Used variables -- */ | ||
+ | var K0 = 0; var P0 = 0; var E_p0 = 0; var L0 = 0; //Energies at i-step | ||
+ | var K1 = 0; var P1 = 0; var E_p1 = 0; var L1 = 0; // Energies at (i+1)-step | ||
+ | var E_m = 0; //Maximum of Energy at the first moment | ||
+ | var t = 0; //Time | ||
+ | |||
+ | var U = []; //Exact solution for wave | ||
+ | var shaft = []; //Objects | ||
+ | |||
+ | var pause = false; | ||
+ | const stretch_graphics = 3; | ||
+ | var help = stretch_graphics * canvasGraph.width; //Scale of graph of energies | ||
+ | var firstCalculation = true; | ||
+ | /* -- */ | ||
− | // | + | //Restart the programm with new parameters |
− | restart.onclick = function() | + | restart.onclick = function(){ |
− | + | N = parseFloat(number_of_objects.value) + 1; | |
− | N = parseFloat(number_of_objects.value) + 1; | ||
scale = canvasSystem.width / N; | scale = canvasSystem.width / N; | ||
+ | scale1 = canvasGraph_2.width / (N + 2); | ||
spf = calcul_speed.value; | spf = calcul_speed.value; | ||
− | |||
− | |||
J = Pi * Db2 * Db2 / 64; | J = Pi * Db2 * Db2 / 64; | ||
C = E * J / l; | C = E * J / l; | ||
Строка 65: | Строка 92: | ||
addSystem(shaft); | addSystem(shaft); | ||
+ | firstCalculation = true; | ||
t = 0; | t = 0; | ||
P1 = 0; | P1 = 0; | ||
K1 = 0; | K1 = 0; | ||
− | + | E_m = 0; | |
− | + | } | |
− | + | ||
− | + | //Pause | |
− | + | pause_button.onclick = function(){ | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | // | ||
− | pause_button.onclick = function() | ||
− | |||
pause = !pause; | pause = !pause; | ||
if(pause == false) | if(pause == false) | ||
Строка 91: | Строка 107: | ||
pause_button.value = "Run"; | pause_button.value = "Run"; | ||
} | } | ||
− | + | ||
− | + | //Calculate all parameters of system | |
− | + | function control(){ | |
− | + | if(!pause){ | |
− | + | /* -- Find the maximum of energy -- */ | |
− | + | if(firstCalculation){ | |
− | + | for (var i = 1; i < N; i++){ | |
− | + | E_m += Q * shaft[i].w * shaft[i].w / 2; | |
− | + | } | |
− | + | ||
+ | for (var i = 1; i < N; i++){ | ||
+ | E_m += C / 2 * (12 * shaft[i].fi * shaft[i].fi - ((shaft[i-1].fi - shaft[i].fi) * (shaft[i-1].fi - shaft[i].fi) + | ||
+ | (shaft[i].fi - shaft[i+1].fi) * (shaft[i].fi - shaft[i+1].fi))); | ||
+ | } | ||
+ | |||
+ | L0 = E_m; | ||
+ | E_p0 = E_m / 2; | ||
+ | firstCalculation = false; | ||
+ | } | ||
+ | /* -- */ | ||
+ | |||
physics(); | physics(); | ||
draw(); | draw(); | ||
− | if(t*help > canvasGraph.width) | + | if(t*help > canvasGraph.width){ |
− | |||
t = 0; | t = 0; | ||
context_g.clearRect(0, 0, canvasGraph.width, canvasGraph.height); | context_g.clearRect(0, 0, canvasGraph.width, canvasGraph.height); | ||
Строка 114: | Строка 140: | ||
draw_Graph_angels(); | draw_Graph_angels(); | ||
+ | //exact_solution_for_wave(t*help); | ||
+ | |||
P0 = P1; | P0 = P1; | ||
K0 = K1; | K0 = K1; | ||
Строка 124: | Строка 152: | ||
t += dt; | t += dt; | ||
} | } | ||
− | + | } | |
− | // | + | //Physics - calculate the positions of objects |
− | function physics() | + | function physics(){ |
− | + | for (var s = 1; s <= spf; s++){ | |
− | + | //Periodic initial conditions | |
− | + | shaft[0].fi = shaft[N-1].fi; | |
− | shaft[0]. | + | shaft[N].fi = shaft[1].fi; |
− | shaft[N]. | ||
− | for (var i = 1; i < N; i++) | + | for (var i = 1; i < N; i++){ |
− | + | shaft[i].M = - 2 * C * (shaft[i-1].fi + 2 * shaft[i].fi) - 2 * C * (2 * shaft[i].fi + shaft[i+1].fi); | |
− | shaft[i].M = - 2 * C * (shaft[i-1]. | ||
} | } | ||
− | for (var i = 1; i < N; i++) | + | for (var i = 1; i < N; i++){ |
− | |||
shaft[i].w += shaft[i].M / Q * dt; | shaft[i].w += shaft[i].M / Q * dt; | ||
− | shaft[i]. | + | shaft[i].fi += shaft[i].w * dt; |
} | } | ||
− | for (var i = 1; i < N; i++) | + | for (var i = 1; i < N; i++){ |
− | |||
shaft[i].M = 0; | shaft[i].M = 0; | ||
} | } | ||
− | + | } | |
− | + | } | |
− | + | //Draw the graph of system | |
− | + | function draw(){ | |
− | + | context_s.clearRect(0, 0, canvasSystem.width, canvasSystem.height); | |
− | |||
− | + | for (var i = 1; i < N; i++){ | |
− | |||
context_s.beginPath(); | context_s.beginPath(); | ||
− | context_s.moveTo(shaft[i].x - (a/2) * Math.sin(shaft[i]. | + | context_s.moveTo(shaft[i].x - (a/2) * Math.sin(shaft[i].fi), shaft[i].y - (a/2) * Math.cos(shaft[i].fi)); |
− | context_s.lineTo(shaft[i].x + (a/2) * Math.sin(shaft[i]. | + | context_s.lineTo(shaft[i].x + (a/2) * Math.sin(shaft[i].fi), shaft[i].y + (a/2) * Math.cos(shaft[i].fi)); |
context_s.closePath(); | context_s.closePath(); | ||
context_s.stroke(); | context_s.stroke(); | ||
− | + | } | |
− | + | } | |
− | // | + | //Draw the graph of angels |
− | function draw_Graph_angels() | + | function draw_Graph_angels(){ |
− | + | context_g_2.clearRect(0, 0, canvasGraph_2.width, canvasGraph_2.height); | |
− | + | ||
− | context_g_2.clearRect(0, 0, canvasGraph_2.width, canvasGraph_2.height); | + | for(var i = 0; i < N; i++){ |
− | + | context_g_2.beginPath(); | |
− | for(var i = 0; i < N; i++) | + | context_g_2.moveTo(scale1 * (i+1), -shaft[i].fi / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2); |
− | + | context_g_2.lineTo(scale1 * (i+2), -shaft[i+1].fi / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2); | |
− | context_g_2.beginPath(); | ||
− | context_g_2.moveTo(scale1 * (i+1), -shaft[i]. | ||
− | context_g_2.lineTo(scale1 * (i+2), -shaft[i+1]. | ||
context_g_2.closePath(); | context_g_2.closePath(); | ||
context_g_2.stroke(); | context_g_2.stroke(); | ||
Строка 183: | Строка 202: | ||
} | } | ||
− | // | + | //Draw the graphics of energies |
− | function draw_Graph_energy(x0, x1) | + | function draw_Graph_energy(x0, x1){ |
− | + | //Potential | |
− | // | ||
context_g_1.beginPath(); | context_g_1.beginPath(); | ||
context_g_1.strokeStyle = "#FF0000"; | context_g_1.strokeStyle = "#FF0000"; | ||
− | context_g_1.moveTo(x0, -P0 / | + | context_g_1.moveTo(x0, -P0 / E_m * canvasGraph_1.height + canvasGraph_1.height); |
− | for (var i = 1; i < N; i++) | + | for (var i = 1; i < N; i++){ |
− | + | P1 += C / 2 * (12 * shaft[i].fi * shaft[i].fi - ((shaft[i-1].fi - shaft[i].fi) * (shaft[i-1].fi - shaft[i].fi) + | |
− | P1 += C / 2 * (12 * shaft[i]. | + | (shaft[i].fi - shaft[i+1].fi) * (shaft[i].fi - shaft[i+1].fi))); |
− | (shaft[i]. | ||
} | } | ||
− | context_g_1.lineTo(x1, -P1 / | + | context_g_1.lineTo(x1, -P1 / E_m * canvasGraph_1.height + canvasGraph_1.height); |
context_g_1.closePath(); | context_g_1.closePath(); | ||
context_g_1.stroke(); | context_g_1.stroke(); | ||
− | // | + | //Kinetical |
context_g_1.beginPath(); | context_g_1.beginPath(); | ||
context_g_1.strokeStyle = "#000000"; | context_g_1.strokeStyle = "#000000"; | ||
− | context_g_1.moveTo(x0, -K0 / | + | context_g_1.moveTo(x0, -K0 / E_m * canvasGraph_1.height + canvasGraph_1.height); |
− | for (var i = 1; i < N; i++) | + | for (var i = 1; i < N; i++){ |
− | |||
K1 += Q * shaft[i].w * shaft[i].w / 2; | K1 += Q * shaft[i].w * shaft[i].w / 2; | ||
} | } | ||
− | context_g_1.lineTo(x1, -K1 / | + | context_g_1.lineTo(x1, -K1 / E_m * canvasGraph_1.height + canvasGraph_1.height); |
context_g_1.closePath(); | context_g_1.closePath(); | ||
context_g_1.stroke(); | context_g_1.stroke(); | ||
− | // | + | //Full energy |
context_g_1.beginPath(); | context_g_1.beginPath(); | ||
context_g_1.strokeStyle = "blue"; | context_g_1.strokeStyle = "blue"; | ||
− | context_g_1.moveTo(x0, -E_p0 / | + | context_g_1.moveTo(x0, -E_p0 / E_m * canvasGraph.height + canvasGraph.height); |
− | E_p1 = K1 + P1; | + | E_p1 = (K1 + P1) / 2; |
− | context_g_1.lineTo(x1, -E_p1 / | + | context_g_1.lineTo(x1, -E_p1 / E_m * canvasGraph.height + canvasGraph.height); |
context_g_1.closePath(); | context_g_1.closePath(); | ||
context_g_1.stroke(); | context_g_1.stroke(); | ||
− | // | + | //Lagrangian |
context_g.beginPath(); | context_g.beginPath(); | ||
context_g.strokeStyle = "orange"; | context_g.strokeStyle = "orange"; | ||
− | context_g.moveTo(x0, -L0 / | + | context_g.moveTo(x0, -L0 / E_m * canvasGraph.height / 2 + canvasGraph.height / 2); |
L1 = K1 - P1; | L1 = K1 - P1; | ||
− | context_g.lineTo(x1, -L1 / | + | context_g.lineTo(x1, -L1 / E_m * canvasGraph.height / 2 + canvasGraph.height / 2); |
context_g.closePath(); | context_g.closePath(); | ||
context_g.stroke(); | context_g.stroke(); | ||
− | } | + | } |
− | // | + | //Add the system of objects |
− | + | function addSystem(shaft){ | |
− | + | for (var i = 0; i < N + 1; i++){ | |
− | |||
− | |||
var shaft_new = []; | var shaft_new = []; | ||
+ | |||
shaft_new.x = scale * i; | shaft_new.x = scale * i; | ||
shaft_new.y = canvasSystem.height / 2; | shaft_new.y = canvasSystem.height / 2; | ||
− | shaft_new. | + | shaft_new.fi = 0; |
shaft_new.w = 0; | shaft_new.w = 0; | ||
shaft_new.M = 0; | shaft_new.M = 0; | ||
Строка 252: | Строка 267: | ||
} | } | ||
− | + | /* --Initial conditions-- */ | |
− | var average_w = 0; // | + | //Random velocities |
− | + | if(all_.checked){ | |
− | + | var average_w = 0; //Average velocity | |
− | + | ||
− | + | for (var i = 0; i < N; i++){ | |
− | average_w += shaft[i]. | + | shaft[i].w = Math.random() * w_c; |
+ | average_w += shaft[i].w; | ||
+ | } | ||
+ | |||
+ | average_w /= N; | ||
+ | |||
+ | for (var i = 0; i < N; i++){ | ||
+ | shaft[i].w -= average_w; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // N/10 - Central part of objects by sin | ||
+ | if(part.checked){ | ||
+ | for (var i = Math.floor(-Math.floor(N / 10) / 2); i < Math.floor(Math.floor(N / 10) / 2); i++){ | ||
+ | shaft[Math.floor(N / 2) + i + 1].fi = | ||
+ | Math.sin(2 * Pi * (Math.floor(Math.floor(N / 10) / 2) - i) * (Math.floor(Math.floor(N / 10) / 2) + i) / N/2); | ||
+ | } | ||
} | } | ||
− | + | //Central object | |
+ | if(one.checked){ | ||
+ | shaft[Math.floor(N / 2)].w = w_c; | ||
+ | } | ||
+ | |||
+ | //Wave | ||
+ | if(wave.checked){ | ||
+ | for (var i = 1; i < N; i++){ | ||
+ | shaft[i].fi = Math.sin(k_ * (l * i)); | ||
+ | shaft[i].w = -w_ * Math.cos(k_ * (l * i)); | ||
+ | } | ||
+ | } | ||
+ | } | ||
− | for (var i = | + | //Exact solution for wave |
− | + | function exact_solution_for_wave(t) { | |
− | + | for (var i = 1; i < N; i++){ | |
− | + | U[i] = Math.sin(k_ * (l * i) - w_ * t / 200); | |
+ | } | ||
+ | //context_g_2.clearRect(0, 0, canvasGraph_2.width, canvasGraph_2.height); | ||
+ | for(var i = 0; i < N; i++){ | ||
+ | context_g_2.beginPath(); | ||
+ | context_g_2.moveTo(scale1 * (i+1), -U[i] / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2); | ||
+ | context_g_2.lineTo(scale1 * (i+2), -U[i+1] / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2); | ||
+ | context_g_2.closePath(); | ||
+ | context_g_2.stroke(); | ||
} | } | ||
− | + | } | |
− | |||
− | |||
− | |||
− | + | addSystem(shaft); //Adding our system of objects | |
− | addSystem(shaft); | ||
− | + | setInterval(control, frequency); | |
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Строка 284: | Строка 331: | ||
<!DOCTYPE html> | <!DOCTYPE html> | ||
<html> | <html> | ||
− | |||
− | |||
<body> | <body> | ||
− | |||
− | |||
<canvas id="canvasSystem" width="1200" height="300" style="border:1px solid #000000;"></canvas><br><br> | <canvas id="canvasSystem" width="1200" height="300" style="border:1px solid #000000;"></canvas><br><br> | ||
− | Number of objects: <input type="number" id="number_of_objects" value="500" step=1 style="width: 5em"> | + | Number of objects: <input type="number" id="number_of_objects" value="500" step=1 style="width: 5em">, |
− | + | Calculation speed: <input type="range" id="calcul_speed" value="100" step=0.01 min=10 max=300><br> | |
− | + | ||
+ | Initial conditions:<br> | ||
+ | <input type="radio" checked="checked" name="initial_conditions" id="all_"/>Random velocities<br> | ||
+ | <input type="radio" name="initial_conditions" id="part"/>Central part of objects by sin<br> | ||
+ | <input type="radio" name="initial_conditions" id="one"/>One object<br> | ||
+ | <input type="radio" name="initial_conditions" id="wave"/>Wave<br> | ||
<input type="button" id="restart" value="Restart"> | <input type="button" id="restart" value="Restart"> | ||
<input type="button" id="pause_button" value="Pause"><br><br> | <input type="button" id="pause_button" value="Pause"><br><br> | ||
− | |||
Graphics:<br> | Graphics:<br> | ||
<canvas id="canvasGraph" width="600" height="300" style="border:1px solid #000000;"></canvas> | <canvas id="canvasGraph" width="600" height="300" style="border:1px solid #000000;"></canvas> | ||
<canvas id="canvasGraph_1" width="600" height="300" style="border:1px solid #000000;"></canvas><br> | <canvas id="canvasGraph_1" width="600" height="300" style="border:1px solid #000000;"></canvas><br> | ||
L<hr align="left" width="50" size="3" color="orange" /> | L<hr align="left" width="50" size="3" color="orange" /> | ||
− | E<hr align="left" width="50" size="3" color="blue" /> | + | E / 2<hr align="left" width="50" size="3" color="blue" /> |
K<hr align="left" width="50" size="3" color="#000000" /> | K<hr align="left" width="50" size="3" color="#000000" /> | ||
P<hr align="left" width="50" size="3" color="#FF0000" /><br> | P<hr align="left" width="50" size="3" color="#FF0000" /><br> | ||
+ | |||
Angles:<br> | Angles:<br> | ||
<canvas id="canvasGraph_2" width="1200" height="300" style="border:1px solid #000000;"></canvas><br> | <canvas id="canvasGraph_2" width="1200" height="300" style="border:1px solid #000000;"></canvas><br> | ||
Строка 311: | Строка 359: | ||
</body> | </body> | ||
</html> | </html> | ||
− | |||
− | |||
− | |||
[https://bitbucket.org/GA__GA/spin-degree-of-freedom/get/c518f9b3fb9b.zip Скачать архив] | [https://bitbucket.org/GA__GA/spin-degree-of-freedom/get/c518f9b3fb9b.zip Скачать архив] | ||
'''Текст программы на языке JavaScript (разработчик [[Александров Александр]]):''' | '''Текст программы на языке JavaScript (разработчик [[Александров Александр]]):''' |
Версия 20:02, 22 мая 2016
Виртуальная лаборатория > Цепочка частиц с вращательными степенями свободыКраткое описание
Рассматривается совокупность твердых тел, образующих цепочки. Центры масс фиксированы. Взаимодействия осуществляются посредством балок Бернулли-Эйлера, соединяющих тела.
Реализации цепочки
1 window.addEventListener("load", MainSystem, true);
2
3 function MainSystem(){
4 var context_s = canvasSystem.getContext('2d');
5 var context_g = canvasGraph.getContext('2d');
6 var context_g_1 = canvasGraph_1.getContext('2d');
7 var context_g_2 = canvasGraph_2.getContext('2d');
8
9 const Pi = 3.1415926;
10 const m0 = 1;
11 const T0 = 1;
12 const l0 = 1;
13 const E0 = 1;
14
15 //Width of canvas - width of browser
16 const distance_between_canvases = 5; //5px
17 canvasSystem.width = document.body.clientWidth;
18 canvasGraph.width = document.body.clientWidth / 2 - distance_between_canvases;
19 canvasGraph_1.width = document.body.clientWidth / 2 - distance_between_canvases;
20 canvasGraph_2.width = document.body.clientWidth;
21
22 /* -- Used constans -- */
23 var Db = 0.1 * l0; // Diameter of beam
24 const l = 30 * l0; //Length of beam
25 const a = 60 * l0; //Length of object
26 var Db2 = Db * Db;
27 var J = Pi * Db2 * Db2 / 64; //Polar moment of inertia
28 const E = 10000000 * E0; //Youngs modulus
29 var C = E * J / l;
30 var N = parseFloat(number_of_objects.value) + 1; //number_of_objects.value is number of objects
31 const m = 0.01 * m0; //Mass of object
32 const Q = m * a * a / 12; //Moment of inertia
33 const w_c = Math.sqrt(2 * C / Q); //Self frequency
34
35 const fps = 50; // frames per second
36 var spf = calcul_speed.value; // steps per frame
37 const frequency = 1000 / fps; //frequency of call function - 1000 milliseconds/ fps
38 const dt = 0.05 * T0 / fps; //Step of integration
39
40 var scale = canvasSystem.width / N; //Scale of graph of system
41 var scale1 = canvasGraph_2.width / (N + 2); //Scale of graph of angels
42
43 //For wave
44 const n = 1; //Number of full-wave
45 var k_ = 2 * Pi / (l * (N - 2) * n); //Spatial frequencyw
46 var w_ = Math.sqrt((-2 * C / Q * l * l) * k_ * k_ + (12 * C / Q));
47
48 /* -- Used variables -- */
49 var K0 = 0; var P0 = 0; var E_p0 = 0; var L0 = 0; //Energies at i-step
50 var K1 = 0; var P1 = 0; var E_p1 = 0; var L1 = 0; // Energies at (i+1)-step
51 var E_m = 0; //Maximum of Energy at the first moment
52 var t = 0; //Time
53
54 var U = []; //Exact solution for wave
55 var shaft = []; //Objects
56
57 var pause = false;
58 const stretch_graphics = 3;
59 var help = stretch_graphics * canvasGraph.width; //Scale of graph of energies
60 var firstCalculation = true;
61 /* -- */
62
63 //Restart the programm with new parameters
64 restart.onclick = function(){
65 N = parseFloat(number_of_objects.value) + 1;
66 scale = canvasSystem.width / N;
67 scale1 = canvasGraph_2.width / (N + 2);
68 spf = calcul_speed.value;
69 J = Pi * Db2 * Db2 / 64;
70 C = E * J / l;
71
72 context_s.clearRect(0, 0, canvasSystem.width, canvasSystem.height);
73 context_g.clearRect(0, 0, canvasGraph.width, canvasGraph.height);
74 context_g_1.clearRect(0, 0, canvasGraph_1.width, canvasGraph_1.height);
75 context_g_2.clearRect(0, 0, canvasGraph_2.width, canvasGraph_2.height);
76
77 shaft = [];
78 addSystem(shaft);
79
80 firstCalculation = true;
81 t = 0;
82 P1 = 0;
83 K1 = 0;
84 E_m = 0;
85 }
86
87 //Pause
88 pause_button.onclick = function(){
89 pause = !pause;
90 if(pause == false)
91 pause_button.value = "Pause";
92 else
93 pause_button.value = "Run";
94 }
95
96 //Calculate all parameters of system
97 function control(){
98 if(!pause){
99 /* -- Find the maximum of energy -- */
100 if(firstCalculation){
101 for (var i = 1; i < N; i++){
102 E_m += Q * shaft[i].w * shaft[i].w / 2;
103 }
104
105 for (var i = 1; i < N; i++){
106 E_m += C / 2 * (12 * shaft[i].fi * shaft[i].fi - ((shaft[i-1].fi - shaft[i].fi) * (shaft[i-1].fi - shaft[i].fi) +
107 (shaft[i].fi - shaft[i+1].fi) * (shaft[i].fi - shaft[i+1].fi)));
108 }
109
110 L0 = E_m;
111 E_p0 = E_m / 2;
112 firstCalculation = false;
113 }
114 /* -- */
115
116 physics();
117 draw();
118
119 if(t*help > canvasGraph.width){
120 t = 0;
121 context_g.clearRect(0, 0, canvasGraph.width, canvasGraph.height);
122 context_g_1.clearRect(0, 0, canvasGraph_1.width, canvasGraph_1.height);
123 }
124
125 draw_Graph_energy(t*help, (t + dt)*help);
126 draw_Graph_angels();
127
128 //exact_solution_for_wave(t*help);
129
130 P0 = P1;
131 K0 = K1;
132 L0 = L1;
133 E_p0 = E_p1;
134 E_p1 = 0;
135 L1 = 0;
136 P1 = 0;
137 K1 = 0;
138 t += dt;
139 }
140 }
141
142 //Physics - calculate the positions of objects
143 function physics(){
144 for (var s = 1; s <= spf; s++){
145 //Periodic initial conditions
146 shaft[0].fi = shaft[N-1].fi;
147 shaft[N].fi = shaft[1].fi;
148
149 for (var i = 1; i < N; i++){
150 shaft[i].M = - 2 * C * (shaft[i-1].fi + 2 * shaft[i].fi) - 2 * C * (2 * shaft[i].fi + shaft[i+1].fi);
151 }
152
153 for (var i = 1; i < N; i++){
154 shaft[i].w += shaft[i].M / Q * dt;
155 shaft[i].fi += shaft[i].w * dt;
156 }
157
158 for (var i = 1; i < N; i++){
159 shaft[i].M = 0;
160 }
161 }
162 }
163
164 //Draw the graph of system
165 function draw(){
166 context_s.clearRect(0, 0, canvasSystem.width, canvasSystem.height);
167
168 for (var i = 1; i < N; i++){
169 context_s.beginPath();
170 context_s.moveTo(shaft[i].x - (a/2) * Math.sin(shaft[i].fi), shaft[i].y - (a/2) * Math.cos(shaft[i].fi));
171 context_s.lineTo(shaft[i].x + (a/2) * Math.sin(shaft[i].fi), shaft[i].y + (a/2) * Math.cos(shaft[i].fi));
172 context_s.closePath();
173 context_s.stroke();
174 }
175 }
176
177 //Draw the graph of angels
178 function draw_Graph_angels(){
179 context_g_2.clearRect(0, 0, canvasGraph_2.width, canvasGraph_2.height);
180
181 for(var i = 0; i < N; i++){
182 context_g_2.beginPath();
183 context_g_2.moveTo(scale1 * (i+1), -shaft[i].fi / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2);
184 context_g_2.lineTo(scale1 * (i+2), -shaft[i+1].fi / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2);
185 context_g_2.closePath();
186 context_g_2.stroke();
187 }
188 }
189
190 //Draw the graphics of energies
191 function draw_Graph_energy(x0, x1){
192 //Potential
193 context_g_1.beginPath();
194 context_g_1.strokeStyle = "#FF0000";
195 context_g_1.moveTo(x0, -P0 / E_m * canvasGraph_1.height + canvasGraph_1.height);
196
197 for (var i = 1; i < N; i++){
198 P1 += C / 2 * (12 * shaft[i].fi * shaft[i].fi - ((shaft[i-1].fi - shaft[i].fi) * (shaft[i-1].fi - shaft[i].fi) +
199 (shaft[i].fi - shaft[i+1].fi) * (shaft[i].fi - shaft[i+1].fi)));
200 }
201
202 context_g_1.lineTo(x1, -P1 / E_m * canvasGraph_1.height + canvasGraph_1.height);
203 context_g_1.closePath();
204 context_g_1.stroke();
205
206 //Kinetical
207 context_g_1.beginPath();
208 context_g_1.strokeStyle = "#000000";
209 context_g_1.moveTo(x0, -K0 / E_m * canvasGraph_1.height + canvasGraph_1.height);
210
211 for (var i = 1; i < N; i++){
212 K1 += Q * shaft[i].w * shaft[i].w / 2;
213 }
214
215 context_g_1.lineTo(x1, -K1 / E_m * canvasGraph_1.height + canvasGraph_1.height);
216 context_g_1.closePath();
217 context_g_1.stroke();
218
219 //Full energy
220 context_g_1.beginPath();
221 context_g_1.strokeStyle = "blue";
222 context_g_1.moveTo(x0, -E_p0 / E_m * canvasGraph.height + canvasGraph.height);
223
224 E_p1 = (K1 + P1) / 2;
225
226 context_g_1.lineTo(x1, -E_p1 / E_m * canvasGraph.height + canvasGraph.height);
227 context_g_1.closePath();
228 context_g_1.stroke();
229
230 //Lagrangian
231 context_g.beginPath();
232 context_g.strokeStyle = "orange";
233 context_g.moveTo(x0, -L0 / E_m * canvasGraph.height / 2 + canvasGraph.height / 2);
234
235 L1 = K1 - P1;
236
237 context_g.lineTo(x1, -L1 / E_m * canvasGraph.height / 2 + canvasGraph.height / 2);
238 context_g.closePath();
239 context_g.stroke();
240 }
241
242 //Add the system of objects
243 function addSystem(shaft){
244 for (var i = 0; i < N + 1; i++){
245 var shaft_new = [];
246
247 shaft_new.x = scale * i;
248 shaft_new.y = canvasSystem.height / 2;
249 shaft_new.fi = 0;
250 shaft_new.w = 0;
251 shaft_new.M = 0;
252 shaft[shaft.length] = shaft_new;
253 }
254
255 /* --Initial conditions-- */
256 //Random velocities
257 if(all_.checked){
258 var average_w = 0; //Average velocity
259
260 for (var i = 0; i < N; i++){
261 shaft[i].w = Math.random() * w_c;
262 average_w += shaft[i].w;
263 }
264
265 average_w /= N;
266
267 for (var i = 0; i < N; i++){
268 shaft[i].w -= average_w;
269 }
270 }
271
272 // N/10 - Central part of objects by sin
273 if(part.checked){
274 for (var i = Math.floor(-Math.floor(N / 10) / 2); i < Math.floor(Math.floor(N / 10) / 2); i++){
275 shaft[Math.floor(N / 2) + i + 1].fi =
276 Math.sin(2 * Pi * (Math.floor(Math.floor(N / 10) / 2) - i) * (Math.floor(Math.floor(N / 10) / 2) + i) / N/2);
277 }
278 }
279
280 //Central object
281 if(one.checked){
282 shaft[Math.floor(N / 2)].w = w_c;
283 }
284
285 //Wave
286 if(wave.checked){
287 for (var i = 1; i < N; i++){
288 shaft[i].fi = Math.sin(k_ * (l * i));
289 shaft[i].w = -w_ * Math.cos(k_ * (l * i));
290 }
291 }
292 }
293
294 //Exact solution for wave
295 function exact_solution_for_wave(t) {
296 for (var i = 1; i < N; i++){
297 U[i] = Math.sin(k_ * (l * i) - w_ * t / 200);
298 }
299 //context_g_2.clearRect(0, 0, canvasGraph_2.width, canvasGraph_2.height);
300 for(var i = 0; i < N; i++){
301 context_g_2.beginPath();
302 context_g_2.moveTo(scale1 * (i+1), -U[i] / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2);
303 context_g_2.lineTo(scale1 * (i+2), -U[i+1] / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2);
304 context_g_2.closePath();
305 context_g_2.stroke();
306 }
307 }
308
309 addSystem(shaft); //Adding our system of objects
310
311 setInterval(control, frequency);
312 }
<syntaxhighlight lang="html5" line start="1" enclose="div">
<!DOCTYPE html>
<html>
<body>
<canvas id="canvasSystem" width="1200" height="300" style="border:1px solid #000000;"></canvas>
Number of objects: <input type="number" id="number_of_objects" value="500" step=1 style="width: 5em">,
Calculation speed: <input type="range" id="calcul_speed" value="100" step=0.01 min=10 max=300>
Initial conditions:
<input type="radio" checked="checked" name="initial_conditions" id="all_"/>Random velocities
<input type="radio" name="initial_conditions" id="part"/>Central part of objects by sin
<input type="radio" name="initial_conditions" id="one"/>One object
<input type="radio" name="initial_conditions" id="wave"/>Wave
<input type="button" id="restart" value="Restart">
<input type="button" id="pause_button" value="Pause">
Graphics:
<canvas id="canvasGraph" width="600" height="300" style="border:1px solid #000000;"></canvas>
<canvas id="canvasGraph_1" width="600" height="300" style="border:1px solid #000000;"></canvas>
E / 2
K
P
Angles:
<canvas id="canvasGraph_2" width="1200" height="300" style="border:1px solid #000000;"></canvas>
<script src="simulation.js"></script> </body> </html>
Текст программы на языке JavaScript (разработчик Александров Александр):