Интерактивная модель простейшей колебательной системы — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
 
 
(не показано 7 промежуточных версий 2 участников)
Строка 1: Строка 1:
 +
[[en:Interactive harmonic oscillator model]]
 
[[Виртуальная лаборатория]] > [[Интерактивная модель простейшей колебательной системы]] <HR>
 
[[Виртуальная лаборатория]] > [[Интерактивная модель простейшей колебательной системы]] <HR>
  
 
Левая клавиша мыши по грузу - перетаскивание.
 
Левая клавиша мыши по грузу - перетаскивание.
  
Левая клавиша мыши по полю - заморозить систему.
+
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tcvetkov/Spring/Spring_v2-1_release/Spring.html |width=645 |height=565 |border=0 }}
{{#css:/htmlets/jquery-ui.css}}
 
<addscript src=ocanvas-251/><addscript src=osc_01/><addscript src=jquery_min_new/><addscript src=jquery-ui_min/>
 
<addscript src=TM/><addscript src=jquery_flot/><addscript src=jquery_flot_axislabels/><htmlet nocache="yes">osc_TM</htmlet>
 
  
Текст программы на языке JavaScript (разработчики [[Цветков Денис]], [[Кривцов Антон]], использована библиотека [http://ocanvas.org/ oCanvas]): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default">
+
Скачать [[Медиа:Spring_v2-1_release.zip|Spring_v2-1_release.zip]].
Файл '''"osc_01.js"'''
 
<source lang="javascript" first-line="1">
 
function MainMech(canvas) {
 
  
    // Предварительные установки   
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''Текст программы на языке JavaScript (разработчики [[Цветков Денис]], [[Кривцов Антон]], использована библиотека для построения графиков [http://www.flotcharts.org/ Flot]):''' <div class="mw-collapsible-content">
 +
Файл '''"Spring.js"'''
 +
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 +
window.addEventListener("load", Main_Spring, true);
 +
function Main_Spring() {
  
     var context = canvas.getContext("2d");
+
     var canvas = spring_canvas;
 +
    canvas.onselectstart = function () {return false;};    // запрет выделения canvas
 +
    var ctx = canvas.getContext("2d");                     // на ctx происходит рисование
 +
    var w = canvas.width;                                  // ширина окна в расчетных координатах
 +
    var h = canvas.height;                                  // высота окна в расчетных координатах
  
     const Pi = 3.1415926;         // число "пи"
+
     var Pi = 3.1415926;             // число "пи"
  
     const m0 = 1;         // масштаб массы
+
     var m0 = 1;                 // масштаб массы
     const T0 = 1;         // масштаб времени (период колебаний исходной системы)
+
     var T0 = 1;                 // масштаб времени (период колебаний исходной системы)
  
     const k0 = 2 * Pi / T0;          // масштаб частоты
+
     var k0 = 2 * Pi / T0;          // масштаб частоты
     const C0 = m0 * k0 * k0;          // масштаб жесткости
+
     var C0 = m0 * k0 * k0;          // масштаб жесткости
     const B0 = 2 * m0 * k0;       // масштаб вязкости
+
     var B0 = 2 * m0 * k0;           // масштаб вязкости
  
 
     // *** Задание физических параметров ***
 
     // *** Задание физических параметров ***
Строка 31: Строка 35:
 
     var C = 1 * C0;                // жесткость
 
     var C = 1 * C0;                // жесткость
 
     var B = .1 * B0;                // вязкость
 
     var B = .1 * B0;                // вязкость
 +
    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_B.value = (B / B0).toFixed(1); number_B.value = (B / B0).toFixed(1);
  
 
     // *** Задание вычислительных параметров ***
 
     // *** Задание вычислительных параметров ***
  
     const fps = 50;       // frames per second - число кадров в секунду (качечтво отображения)
+
     var fps = 60;               // frames per second - число кадров в секунду (качечтво отображения)
//    const fps = 4 * 29;       // frames per second - число кадров в секунду (качечтво отображения)
+
     var spf = 10;               // steps per frame  - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета)
     const spf = 20;       // steps per frame  - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета)
+
     var dt  = 0.05 * T0 / fps;       // шаг интегрирования (качество расчета)
     const dt  = 0.05 * T0 / fps;   // шаг интегрирования (качество расчета)
 
 
     var steps = 0;                      // количество шагов интегрирования
 
     var steps = 0;                      // количество шагов интегрирования
  
     // Установка слайдеров значений
+
     function setM(new_m) {m = new_m * m0;}
 
+
     function setC(new_C) {C = new_C * C0;}
    var TM_obj = new TM();              // экземпляр библиотеки для добавления слайдеров
+
     function setB(new_B) {B = new_B * B0;}
 
 
    // функции, запускающиеся при перемещении слайдера
 
    this.setM = function(new_m){m = new_m * m0;};          // new_m - значение на слайдере
 
     this.setC = function(new_C){C = new_C * C0;};
 
     this.setB = function(new_B){B = new_B * B0;};
 
 
 
    TM_obj.addInputSlider(
 
        "#input_slider_m", "#input_m",      // html-элементы слайдера и поля ввода
 
        0.01, 10, 0.01, 1,                  // мин. значение; макс. значение; шаг; начальное значение
 
        this.setM,                          // ссылка на функцию для слайдера (см. выше)
 
        "onMPress");                        // название функции в html-элементе <input onKeyUp="...">
 
    TM_obj.addInputSlider("#input_slider_C", "#input_C", 0, 10, 0.01, 1, this.setC, "onCPress");
 
    TM_obj.addInputSlider("#input_slider_B", "#input_B", 0, 10, 0.01, 0.1, this.setB, "onBPress");
 
  
 +
    slider_m.oninput = function() {number_m.value = slider_m.value;      setM(slider_m.value);};
 +
    number_m.oninput = function() {slider_m.value = number_m.value;      setM(number_m.value);};
 +
    slider_C.oninput = function() {number_C.value = slider_C.value;      setC(slider_C.value);};
 +
    number_C.oninput = function() {slider_C.value = number_C.value;      setC(number_C.value);};
 +
    slider_B.oninput = function() {number_B.value = slider_B.value;      setB(slider_B.value);};
 +
    number_B.oninput = function() {slider_B.value = number_B.value;      setB(number_B.value);};
  
 
     var count = true;      // проводить ли расчет системы
 
     var count = true;      // проводить ли расчет системы
 
     var v = 0; // скорость тела
 
     var v = 0; // скорость тела
 
    // создаем объект, связанный с элементом canvas на html странице
 
    var ocanvas = oCanvas.create({
 
        canvas: "#canvasMech",        // canvasMech - id объекта canvas на html странице
 
        fps: fps                      // сколько кадров в секунду
 
    });
 
  
 
     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;
  
     // создаем пружину
+
     // параметры пружины
     const coil = 10;        // количество витков
+
     var coil = 10;        // количество витков
     const startX = 0;      // закрепление пружины
+
     var startX = 0;      // закрепление пружины
    var lines = [];        // этот массив будет содержать ссылки на линии
 
    for (var i = 0; i < coil; i++ ) {
 
        lines[i] = ocanvas.display.line({
 
            start: { x: startX, y: y0+rh/2 },
 
            end: { x: startX, y: y0+rh/2 },
 
            stroke: "1px #0aa"
 
        }).add();
 
    }
 
  
     // создаем прямоугольник
+
     // создаем прямоугольник-грузик
     var rect = ocanvas.display.rectangle({
+
     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)"    // цвет
     }).add();
+
     };
  
 
     // захват прямоугольника мышью
 
     // захват прямоугольника мышью
     rect.dragAndDrop({
+
     var mx_;                                    // буфер позиции мыши (для расчета скорости при отпускании шара)
    changeZindex: true,          // если много объектов - захваченный будет нарисован спереди
+
    document.onmousedown = function(e) {       // функция при нажатии клавиши мыши
    start: function () { count = false; this.fill = "rgba(0, 0, 255, 0.5)"; },  // отключаем расчет и делаем объект полупрозрачным
+
        var m = mouseCoords(e);                // получаем расчетные координаты курсора мыши
         move:  function () { this.y = y0;     v = 0;     drawSpring();}, // запрещаем перемещение по вертикали
+
 
         end: function ()   { count = true;     this.fill = "rgba(0, 0, 255, 1)"; }     // включаем расчет и убираем полупрозрачность
+
        var x = rect.x;
     });
+
        var xw = rect.x + rect.width;
 +
        var y = rect.y;
 +
        var yh = rect.y + rect.height;
 +
        if (x <= m.x && xw >= m.x  && y <= m.y && yh >= m.y) {
 +
            if (e.which == 1) {                         // нажата левая клавиша мыши
 +
                rect.xPlus = rect.x - m.x;              // сдвиг курсора относительно грузика по x
 +
                rect.yPlus = rect.y - m.y;              // сдвиг курсора относительно грузика по y
 +
                mx_ = m.x;
 +
                count = false;
 +
                document.onmousemove = mouseMove;       // пока клавиша нажата - работает функция перемещения
 +
            }
 +
         }
 +
    };
 +
 
 +
    document.onmouseup = function(e) {         // функция при отпускании клавиши мыши
 +
        document.onmousemove = null;             // когда клавиша отпущена - функции перемещения нету
 +
        count = true;
 +
    };
 +
 
 +
    function mouseMove(e) {                    // функция при перемещении мыши, работает только с зажатой ЛКМ
 +
         var m = mouseCoords(e);                // получаем расчетные координаты курсора мыши
 +
        rect.x = m.x + rect.xPlus;
 +
//        v = 6.0 * (m.x - mx_) / dt / fps;    // сохранение инерции
 +
        v = 0;
 +
        mx_ = m.x;
 +
     }
  
     ocanvas.bind("mousedown", function () {count = false;}); // заморозить фигуру при клике на поле
+
     function mouseCoords(e) {                   // функция возвращает расчетные координаты курсора мыши
 +
        var m = [];
 +
        var rect = canvas.getBoundingClientRect();
 +
        m.x = (e.clientX - rect.left);
 +
        m.y = (e.clientY - rect.top);
 +
        return m;
 +
    }
  
 +
    // график
 
     var vGraph = new TM_graph(                  // определить график
 
     var vGraph = new TM_graph(                  // определить график
 
         "#vGraph",                              // на html-элементе #vGraph
 
         "#vGraph",                              // на html-элементе #vGraph
        "steps", "x",                          // подписи на осях
 
 
         250,                                    // сколько шагов по оси "x" отображается
 
         250,                                    // сколько шагов по оси "x" отображается
 
         -1, 1, 0.2);                            // мин. значение оси Y, макс. значение оси Y, шаг по оси Y
 
         -1, 1, 0.2);                            // мин. значение оси Y, макс. значение оси Y, шаг по оси Y
  
 +
    function control() {
 +
        calculate();
 +
        draw();
 +
        requestAnimationFrame(control);
 +
    }
 +
    control();
 +
//    setInterval(control, 1000 / fps);                      // Запуск системы
  
     function dynamics(){                             // интегрирование по времени
+
     function calculate() {
      if (!count) return;
+
        if (!count) return;
      for (var s=1; s<=spf; s++) {
+
        for (var s=1; s<=spf; s++) {
 
             var f =  - C * (rect.x - x0) - B * v;
 
             var f =  - C * (rect.x - x0) - B * v;
 
             v += f / m * dt;
 
             v += f / m * dt;
                rect.x += v * dt;
+
            rect.x += v * dt;
  
 
             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);  // подать данные на график
            drawSpring();
+
        }
    }
+
 
 
     }
 
     }
  
     function drawSpring() {
+
     function draw() {
         for (var i = 0; i < coil; i++ ) {
+
        ctx.clearRect(0, 0, w, h);
             lines[i].start.x = startX + ((rect.x-startX) + rw/2)/coil*i;
+
 
            lines[i].end.x =    startX + ((rect.x-startX) + rw/2)/coil*(i+1);
+
        ctx.strokeStyle = "#0aa";
            lines[i].start.y = y0+rh/2 + ((i%2==0)?1:-1)*30;
+
        ctx.beginPath();
             lines[i].end.y =   y0+rh/2 + ((i%2==0)?-1:1)*30;
+
        ctx.moveTo(0, y0+rh/2);
            if (i==0) lines[i].start.y = y0+rh/2;
+
         for (var i = 1; i <= coil + 1; i++ ) {
             if (i==(coil-1)) lines[i].end.y =  y0+rh/2;
+
             var x;
 +
            var y;
 +
            if (i != coil + 1) {
 +
                x = startX + ((rect.x - startX))/coil*i - ((rect.x - startX))/coil/2;
 +
                y = y0+rh/2 + ((i%2==0)?1:-1)*30;
 +
             } else {
 +
                x = startX + ((rect.x - startX))/coil*i - ((rect.x - startX))/coil;
 +
                y = y0+rh/2;
 +
             }
 +
 
 +
            ctx.lineTo(x, y);
 
         }
 
         }
 +
        ctx.stroke();
 +
 +
        ctx.fillStyle = "#0000ff";
 +
        ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
 
     }
 
     }
 
    ocanvas.setLoop(dynamics).start();            // функция, выполняющаяся на каждом шаге
 
 
}
 
}
</source>
+
</syntaxhighlight>
Файл '''"osc.html"'''
+
Файл '''"Spring.html"'''
<source lang="html" first-line="1">
+
<syntaxhighlight lang="html5" line start="1" enclose="div">
 
<!DOCTYPE html>
 
<!DOCTYPE html>
 
<html>
 
<html>
 
<head>
 
<head>
     <title>Simple Mechanics</title>
+
     <meta charset="UTF-8" />
     <script src="ocanvas.min.js"></script>
+
     <title>Пружина</title>
     <script src="osc_01.js"></script>
+
     <script src="Spring.js"></script>
 
     <script src="jquery.min.js"></script>
 
     <script src="jquery.min.js"></script>
    <link rel="stylesheet" href="jquery-ui.css" />
+
     <script src="jquery.flot.js"></script>
     <script src="jquery-ui.min.js"></script>
+
     <script src="TM_v2-1.js"></script>
    <script src="TM.js"></script>
 
 
 
    <script language="javascript" type="text/javascript" src="flot/jquery.flot.js"></script>
 
     <script language="javascript" type="text/javascript" src="jquery.flot.axislabels.js"></script>
 
 
</head>
 
</head>
 
<body>
 
<body>
     <div style="float:left;">
+
     <canvas id="spring_canvas" width="600" height="100" style="border:1px solid #000000;"></canvas><br>
        <canvas id="canvasMech" width="600" height="100" style="border:1px solid #000000; float: left;"></canvas>
+
     <input type="range" id="slider_m" min="0.01" max="10" step=0.01 style="width: 150px;" />
        <script type="text/javascript">MainMech(document.getElementById('canvasMech'));</script>
+
    m = <input type="number" id="number_m" min="0.01" max="10" step=0.01 style="width: 50px;" /><br>
     </div>
+
    <input type="range" id="slider_C" min="0" max="10" step=0.01 style="width: 150px;" />
 
+
    C = <input type="number" id="number_C" min="0" max="10" step=0.01 style="width: 50px;" /><br>
    <!--слайдеры-->
+
    <input type="range" id="slider_B" min="0" max="10" step=0.01 style="width: 150px;" />
    <div  style="margin-left:20px; margin-top:20px; margin-bottom:20px; float:left;">
+
    B = <input type="number" id="number_B" min="0" max="10" step=0.01 style="width: 50px;" /><br><br>
        <div id="input_slider_m" style="width:300px; float:left"></div>
 
        <label for="input_m" style="margin-left:20px; float:left">m = </label>
 
        <input onKeyUp="onMPress(event);" type="text" id="input_m" style="margin-left:20px; float:left; border:1; color:#f6931f; font-weight:bold;">
 
    <br><br>
 
        <div id="input_slider_C" style="width:300px; float:left"></div>
 
        <label for="input_C" style="margin-left:20px; float:left">C = </label>
 
        <input onKeyUp="onCPress(event);" type="text" id="input_C" style="margin-left:20px; float:left; border:1; color:#f6931f; font-weight:bold;">
 
    <br><br>
 
        <div id="input_slider_B" style="width:300px; float:left"></div>
 
        <label for="input_B" style="margin-left:20px; float:left">B = </label>
 
        <input onKeyUp="onBPress(event);" type="text" id="input_B" style="margin-left:20px; float:left; border:1; color:#f6931f; font-weight:bold;">
 
    <br><br>
 
 
 
    </div>
 
 
 
    <!--график-->
 
    <div id="vGraph" style="width:600px; height:300px; clear:both;"></div>
 
  
 +
    <table>
 +
        <tr><td>x</td>
 +
            <td><div id="vGraph" style="width:600px; height:300px; clear:both;"></div></td>
 +
        </tr>
 +
        <tr><td></td><td style="text-align: center">steps</td></tr>
 +
    </table>
 
</body>
 
</body>
 
</html>
 
</html>
</source>
+
</syntaxhighlight>
</toggledisplay>
+
</div>
 
+
</div>
[[Media:LIB.zip|LIB.zip]] - библиотеки для построения графиков и слайдеров
 
  
 
== Предлагаемые направления развития стенда ==
 
== Предлагаемые направления развития стенда ==

Текущая версия на 18:27, 18 января 2017

Виртуальная лаборатория > Интерактивная модель простейшей колебательной системы

Левая клавиша мыши по грузу - перетаскивание.

Скачать Spring_v2-1_release.zip.

Текст программы на языке JavaScript (разработчики Цветков Денис, Кривцов Антон, использована библиотека для построения графиков Flot):

Файл "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;};     // запрет выделения canvas
  6     var ctx = canvas.getContext("2d");                      // на ctx происходит рисование
  7     var w = canvas.width;                                   // ширина окна в расчетных координатах
  8     var h = canvas.height;                                  // высота окна в расчетных координатах
  9 
 10     var Pi = 3.1415926;    	      	    // число "пи"
 11 
 12     var m0 = 1;    		      	        // масштаб массы
 13     var T0 = 1;    		      	        // масштаб времени (период колебаний исходной системы)
 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;                 	// масса
 22     var C = 1 * C0;                 	// жесткость
 23     var B = .1 * B0;                 	// вязкость
 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 - число кадров в секунду (качечтво отображения)
 31     var spf = 10;		      	        // steps per frame   - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета)
 32     var dt  = 0.05 * T0 / fps;    	    // шаг интегрирования (качество расчета)
 33     var steps = 0;                      // количество шагов интегрирования
 34 
 35     function setM(new_m) {m = new_m * m0;}
 36     function setC(new_C) {C = new_C * C0;}
 37     function setB(new_B) {B = new_B * B0;}
 38 
 39     slider_m.oninput = function() {number_m.value = slider_m.value;       setM(slider_m.value);};
 40     number_m.oninput = function() {slider_m.value = number_m.value;       setM(number_m.value);};
 41     slider_C.oninput = function() {number_C.value = slider_C.value;       setC(slider_C.value);};
 42     number_C.oninput = function() {slider_C.value = number_C.value;       setC(number_C.value);};
 43     slider_B.oninput = function() {number_B.value = slider_B.value;       setB(slider_B.value);};
 44     number_B.oninput = function() {slider_B.value = number_B.value;       setB(number_B.value);};
 45 
 46     var count = true;       // проводить ли расчет системы
 47     var v = 0;				// скорость тела
 48 
 49     var rw = canvas.width / 30;    	var rh = canvas.height / 1.5;
 50     var x0 = 15 * rw - rw / 2;     	var y0 = rh / 1.33 - rh / 2;
 51 
 52     // параметры пружины
 53     var coil = 10;        // количество витков
 54     var startX = 0;       // закрепление пружины
 55 
 56     // создаем прямоугольник-грузик
 57     var rect = {
 58         x: x0,  width: rw,
 59         y: y0,	height: rh,
 60         fill: "rgba(0, 0, 255, 1)"    	// цвет
 61     };
 62 
 63     // захват прямоугольника мышью
 64     var mx_;                                    // буфер позиции мыши (для расчета скорости при отпускании шара)
 65     document.onmousedown = function(e) {        // функция при нажатии клавиши мыши
 66         var m = mouseCoords(e);                 // получаем расчетные координаты курсора мыши
 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) {                         // нажата левая клавиша мыши
 74                 rect.xPlus = rect.x - m.x;              // сдвиг курсора относительно грузика по x
 75                 rect.yPlus = rect.y - m.y;              // сдвиг курсора относительно грузика по y
 76                 mx_ = m.x;
 77                 count = false;
 78                 document.onmousemove = mouseMove;       // пока клавиша нажата - работает функция перемещения
 79             }
 80         }
 81     };
 82 
 83     document.onmouseup = function(e) {          // функция при отпускании клавиши мыши
 84         document.onmousemove = null;              // когда клавиша отпущена - функции перемещения нету
 85         count = true;
 86     };
 87 
 88     function mouseMove(e) {                     // функция при перемещении мыши, работает только с зажатой ЛКМ
 89         var m = mouseCoords(e);                 // получаем расчетные координаты курсора мыши
 90         rect.x = m.x + rect.xPlus;
 91 //        v = 6.0 * (m.x - mx_) / dt / fps;     // сохранение инерции
 92         v = 0;
 93         mx_ = m.x;
 94     }
 95 
 96     function mouseCoords(e) {                   // функция возвращает расчетные координаты курсора мыши
 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(                  // определить график
106         "#vGraph",                              // на html-элементе #vGraph
107         250,                                    // сколько шагов по оси "x" отображается
108         -1, 1, 0.2);                            // мин. значение оси Y, макс. значение оси Y, шаг по оси Y
109 
110     function control() {
111         calculate();
112         draw();
113         requestAnimationFrame(control);
114     }
115     control();
116 //    setInterval(control, 1000 / fps);                       // Запуск системы
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);   // подать данные на график
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>

Предлагаемые направления развития стенда[править]

  • Моделирование двумерной системы, в которой груз закреплен пружинами с четырех сторон.
  • Моделирование более сложных конфигураций, например, несколько пружин подряд с разной жесткостью.
  • Возможность определения, является ли система апериодичной при заданных условиях.