Редактирование: Интерактивная модель простейшей колебательной системы
Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия | Ваш текст | ||
Строка 1: | Строка 1: | ||
− | |||
[[Виртуальная лаборатория]] > [[Интерактивная модель простейшей колебательной системы]] <HR> | [[Виртуальная лаборатория]] > [[Интерактивная модель простейшей колебательной системы]] <HR> | ||
Левая клавиша мыши по грузу - перетаскивание. | Левая клавиша мыши по грузу - перетаскивание. | ||
− | {{# | + | Левая клавиша мыши по полю - заморозить систему. |
+ | {{#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"> | |
+ | Файл '''"osc_01.js"''' | ||
+ | <source lang="javascript" first-line="1"> | ||
+ | function MainMech(canvas) { | ||
− | + | // Предварительные установки | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | var | + | var context = canvas.getContext("2d"); |
− | |||
− | |||
− | |||
− | |||
− | + | const Pi = 3.1415926; // число "пи" | |
− | + | const m0 = 1; // масштаб массы | |
− | + | const T0 = 1; // масштаб времени (период колебаний исходной системы) | |
− | + | const k0 = 2 * Pi / T0; // масштаб частоты | |
− | + | const C0 = m0 * k0 * k0; // масштаб жесткости | |
− | + | const B0 = 2 * m0 * k0; // масштаб вязкости | |
// *** Задание физических параметров *** | // *** Задание физических параметров *** | ||
Строка 35: | Строка 31: | ||
var C = 1 * C0; // жесткость | var C = 1 * C0; // жесткость | ||
var B = .1 * B0; // вязкость | var B = .1 * B0; // вязкость | ||
− | |||
− | |||
− | |||
// *** Задание вычислительных параметров *** | // *** Задание вычислительных параметров *** | ||
− | + | const fps = 50; // frames per second - число кадров в секунду (качечтво отображения) | |
− | + | // const fps = 4 * 29; // frames per second - число кадров в секунду (качечтво отображения) | |
− | + | const spf = 20; // steps per frame - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета) | |
+ | const dt = 0.05 * T0 / fps; // шаг интегрирования (качество расчета) | ||
var steps = 0; // количество шагов интегрирования | var steps = 0; // количество шагов интегрирования | ||
− | function | + | // Установка слайдеров значений |
− | function | + | |
− | function | + | var TM_obj = new TM(); // экземпляр библиотеки для добавления слайдеров |
+ | |||
+ | // функции, запускающиеся при перемещении слайдера | ||
+ | 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"); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
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; // количество витков | |
− | + | const 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 = { | + | var rect = ocanvas.display.rectangle({ |
− | x: x0, width: rw, | + | x: x0, width: rw, |
− | + | y: y0, height: rh, | |
− | + | fill: "rgba(0, 0, 255, 1)" // цвет | |
− | }; | + | }).add(); |
// захват прямоугольника мышью | // захват прямоугольника мышью | ||
− | + | rect.dragAndDrop({ | |
− | + | changeZindex: true, // если много объектов - захваченный будет нарисован спереди | |
− | + | start: function () { count = false; this.fill = "rgba(0, 0, 255, 0.5)"; }, // отключаем расчет и делаем объект полупрозрачным | |
− | + | move: function () { this.y = y0; v = 0; drawSpring();}, // запрещаем перемещение по вертикали | |
− | + | end: function () { count = true; this.fill = "rgba(0, 0, 255, 1)"; } // включаем расчет и убираем полупрозрачность | |
− | + | }); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | } | ||
− | function | + | ocanvas.bind("mousedown", function () {count = false;}); // заморозить фигуру при клике на поле |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
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 | + | function dynamics(){ // интегрирование по времени |
− | + | if (!count) return; | |
− | + | 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; | |
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 | + | function drawSpring() { |
− | + | for (var i = 0; i < coil; i++ ) { | |
− | + | 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); | |
− | + | lines[i].start.y = y0+rh/2 + ((i%2==0)?1:-1)*30; | |
− | + | lines[i].end.y = y0+rh/2 + ((i%2==0)?-1:1)*30; | |
− | for (var i = | + | if (i==0) lines[i].start.y = y0+rh/2; |
− | + | if (i==(coil-1)) lines[i].end.y = y0+rh/2; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | } | |
− | + | ocanvas.setLoop(dynamics).start(); // функция, выполняющаяся на каждом шаге | |
− | |||
− | |||
} | } | ||
− | </ | + | </source> |
− | Файл '''" | + | Файл '''"osc.html"''' |
− | < | + | <source lang="html" first-line="1"> |
<!DOCTYPE html> | <!DOCTYPE html> | ||
<html> | <html> | ||
<head> | <head> | ||
− | < | + | <title>Simple Mechanics</title> |
− | < | + | <script src="ocanvas.min.js"></script> |
− | <script src=" | + | <script src="osc_01.js"></script> |
<script src="jquery.min.js"></script> | <script src="jquery.min.js"></script> | ||
− | <script src="jquery.flot.js"></script> | + | <link rel="stylesheet" href="jquery-ui.css" /> |
− | <script src=" | + | <script src="jquery-ui.min.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> | ||
− | <canvas id=" | + | <div style="float:left;"> |
− | < | + | <canvas id="canvasMech" width="600" height="100" style="border:1px solid #000000; float: left;"></canvas> |
− | + | <script type="text/javascript">MainMech(document.getElementById('canvasMech'));</script> | |
− | + | </div> | |
− | + | ||
− | + | <!--слайдеры--> | |
− | + | <div style="margin-left:20px; margin-top:20px; margin-bottom:20px; float:left;"> | |
+ | <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> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</body> | </body> | ||
</html> | </html> | ||
− | </ | + | </source> |
− | </ | + | </toggledisplay> |
− | + | ||
+ | [[Media:LIB.zip|LIB.zip]] - библиотеки для построения графиков и слайдеров | ||
== Предлагаемые направления развития стенда == | == Предлагаемые направления развития стенда == |