Цепочка из частиц с вращательными степенями свободы — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
Строка 14: Строка 14:
  
 
window.addEventListener("load", MainSystem, true);
 
window.addEventListener("load", MainSystem, true);
function MainSystem()
+
 
{
+
function MainSystem(){
    var context_s = canvasSystem.getContext('2d');                 // Отрисовка цепочки
+
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 Pi = 3.1415926;                   
    const m0 = 1;                         
+
const m0 = 1;                         
    const T0 = 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;
 
 
    var Db = parseFloat(diameter.value) * l0; // диаметр балки
+
/* -- Used constans -- */
const l = 60 * l0; // длина балки
+
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 * l * l / 12;  // момент инерции стержня
+
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;
Db = parseFloat(diameter.value) * l0; //новый диаметр балки
 
Db2 = Db * Db;
 
 
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;
+
}
const fps = 50;                        // frames per second (качество отображения)
+
 
    var spf = calcul_speed.value;          // steps per frame  (скорость расчёта)
+
//Pause
    const frequency = 1000 / fps; //Время, через которые будет выполнятся код - 1000 миллисекунд / fps
+
pause_button.onclick = function(){
const dt  = 0.05 * T0 / fps;              
 
 
var scale = canvasSystem.width / N;  // Для масштабирования
 
 
var K0 = 0; var P0 = 0; var E_p0 = 0; var L0; // показания энергий на i-шаге
 
var K1 = 0; var P1 = 0; var E_p1 = 0; var L1; // показания энергий на (i+1)-шаге
 
var K_m;    //максимальное значение энергии в начальный момент времени - для масштабирования
 
var t = 0; // время
 
 
//Пауза
 
pause_button.onclick = function()  
 
{
 
 
pause = !pause;   
 
pause = !pause;   
 
if(pause == false)
 
if(pause == false)
Строка 91: Строка 107:
 
pause_button.value = "Run";
 
pause_button.value = "Run";
 
}
 
}
+
 
var pause = false;
+
//Calculate all parameters of system
const stretch_graphics = 3;
+
  function control(){
var help = stretch_graphics * canvasGraph.width; //масштабирование графиков по оси t
+
    if(!pause){
+
/* -- Find the maximum of energy -- */
    // Запуск вычислений
+
if(firstCalculation){
    function control()
+
for (var i = 1; i < N; i++){
{
+
E_m += Q * shaft[i].w * shaft[i].w / 2;
        if(!pause)
+
}
{
+
 
 +
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++){
        for (var s = 1; s <= spf; s++)  
+
    //Periodic initial conditions
        {
+
shaft[0].fi = shaft[N-1].fi;
shaft[0].v = shaft[N-1].v;
+
shaft[N].fi = shaft[1].fi;
shaft[N].v = shaft[1].v;
 
 
 
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].v + 2 * shaft[i].v) - 2 * C * (2 * shaft[i].v + shaft[i+1].v);
 
 
}
 
}
 
 
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].v += shaft[i].w * dt;
+
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()  
+
function draw(){
    {
+
    context_s.clearRect(0, 0, canvasSystem.width, canvasSystem.height);  
        context_s.clearRect(0, 0, canvasSystem.width, canvasSystem.height); // очистить экран
 
 
   
 
   
        for (var i = 1; i < N; i++)
+
    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].v), shaft[i].y - (a/2) * Math.cos(shaft[i].v));
+
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].v), shaft[i].y + (a/2) * Math.cos(shaft[i].v));
+
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);   
var scale1 = canvasGraph_2.width / (N + 2);
+
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].v / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2);
 
context_g_2.lineTo(scale1 * (i+2), -shaft[i+1].v / (Pi/2) * canvasGraph_2.height / 2 + canvasGraph_2.height / 2);
 
 
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 / K_m * canvasGraph_1.height + canvasGraph_1.height);
+
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].v * shaft[i].v - ((shaft[i-1].v - shaft[i].v) * (shaft[i-1].v - shaft[i].v) +  
+
(shaft[i].fi - shaft[i+1].fi) * (shaft[i].fi - shaft[i+1].fi)));
(shaft[i].v - shaft[i+1].v) * (shaft[i].v - shaft[i+1].v)));
 
 
}
 
}
 
 
context_g_1.lineTo(x1, -P1 / K_m * canvasGraph_1.height + canvasGraph_1.height);
+
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 / K_m * canvasGraph_1.height + canvasGraph_1.height);
+
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 / K_m * canvasGraph_1.height + canvasGraph_1.height);
+
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 / K_m * canvasGraph.height + canvasGraph.height);
+
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 / K_m * canvasGraph.height + canvasGraph.height);
+
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 / K_m * canvasGraph.height / 2 + canvasGraph.height / 2);
+
context_g.moveTo(x0, -L0 / E_m * canvasGraph.height / 2 + canvasGraph.height / 2);
 
 
 
L1 = K1 - P1;
 
L1 = K1 - P1;
  
context_g.lineTo(x1, -L1 / K_m * canvasGraph.height / 2 + canvasGraph.height / 2);
+
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)
+
  function addSystem(shaft){
    {
+
  for (var i = 0; i < N + 1; i++){
    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.v = 0;
+
shaft_new.fi = 0;
 
shaft_new.w = 0;
 
shaft_new.w = 0;
 
shaft_new.M = 0;
 
shaft_new.M = 0;
Строка 252: Строка 267:
 
}
 
}
 
 
K_m = 0;
+
/*  --Initial conditions-- */
var average_w = 0; // средняя скорость объектов
+
//Random velocities
// Задаем начальные условия
+
if(all_.checked){
for (var i = 0; i < N; i++)
+
var average_w = 0; //Average velocity
{
+
shaft[i].w = Math.random() * w_c;
+
for (var i = 0; i < N; i++){
average_w += shaft[i].w;
+
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);
 +
}
 
}
 
}
 
 
average_w /= N;
+
//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 = 0; i < N; i++)
+
//Exact solution for wave
{
+
function exact_solution_for_wave(t) {
shaft[i].w -= average_w;
+
for (var i = 1; i < N; i++){
K_m += Q * shaft[i].w * shaft[i].w / 2;
+
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();
 
}
 
}
+
}
E_p0 = K_m;
 
L0 = K_m;
 
    }
 
 
 
shaft = [];
+
addSystem(shaft);       //Adding our system of objects
addSystem(shaft); //Добавление системы стержней
 
  
    setInterval(control, frequency);   
+
  setInterval(control, frequency);   
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
Строка 284: Строка 331:
 
<!DOCTYPE html>
 
<!DOCTYPE html>
 
<html>
 
<html>
<head>
 
</head>
 
 
<body>
 
<body>
<br>
 
<!-- ќбласть дл¤ рисовани¤ системы -->
 
 
<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">,
Diameter of beam: <input type="number" id="diameter" value="0.1" step=0.01 style="width: 5em">c.u.<br>
+
Calculation speed: <input type="range" id="calcul_speed" value="100" step=0.01 min=10 max=300><br>
Calculation speed: <input type="range" id="calcul_speed" value="100" step=0.01 min=10 max=300>
+
 +
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>
</syntaxhighlight>
 
</div>
 
</div>
 
  
 
[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>

L
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 (разработчик Александров Александр):