Интерактивная модель простейшей колебательной системы — различия между версиями
Денис (обсуждение | вклад) |
Wikiadmin (обсуждение | вклад) м (Замена текста — «<source lang="(.*)" first-line="(.*)">» на «<syntaxhighlight lang="$1" line start="$2" enclose="div">») |
||
Строка 9: | Строка 9: | ||
Текст программы на языке JavaScript (разработчики [[Цветков Денис]], [[Кривцов Антон]], использована библиотека для построения графиков [http://www.flotcharts.org/ Flot]): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> | Текст программы на языке JavaScript (разработчики [[Цветков Денис]], [[Кривцов Антон]], использована библиотека для построения графиков [http://www.flotcharts.org/ Flot]): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> | ||
Файл '''"Spring.js"''' | Файл '''"Spring.js"''' | ||
− | < | + | <syntaxhighlight lang="javascript" line start="1" enclose="div"> |
window.addEventListener("load", Main_Spring, true); | window.addEventListener("load", Main_Spring, true); | ||
function Main_Spring() { | function Main_Spring() { | ||
Строка 167: | Строка 167: | ||
</source> | </source> | ||
Файл '''"Spring.html"''' | Файл '''"Spring.html"''' | ||
− | < | + | <syntaxhighlight lang="html" line start="1" enclose="div"> |
<!DOCTYPE html> | <!DOCTYPE html> | ||
<html> | <html> |
Версия 18:53, 8 марта 2015
Виртуальная лаборатория > Интерактивная модель простейшей колебательной системыЛевая клавиша мыши по грузу - перетаскивание.
Скачать Spring_v2-1_release.zip.
Текст программы на языке JavaScript (разработчики Цветков Денис, Кривцов Антон, использована библиотека для построения графиков Flot): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> Файл "Spring.js" <syntaxhighlight lang="javascript" line start="1" enclose="div"> window.addEventListener("load", Main_Spring, true); function Main_Spring() {
var canvas = spring_canvas; canvas.onselectstart = function () {return false;}; // запрет выделения canvas var ctx = canvas.getContext("2d"); // на ctx происходит рисование var w = canvas.width; // ширина окна в расчетных координатах var h = canvas.height; // высота окна в расчетных координатах
var Pi = 3.1415926; // число "пи"
var m0 = 1; // масштаб массы var T0 = 1; // масштаб времени (период колебаний исходной системы)
var k0 = 2 * Pi / T0; // масштаб частоты var C0 = m0 * k0 * k0; // масштаб жесткости var B0 = 2 * m0 * k0; // масштаб вязкости
// *** Задание физических параметров ***
var m = 1 * m0; // масса var C = 1 * C0; // жесткость 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);
// *** Задание вычислительных параметров ***
var fps = 60; // frames per second - число кадров в секунду (качечтво отображения) var spf = 10; // steps per frame - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета) var dt = 0.05 * T0 / fps; // шаг интегрирования (качество расчета) var steps = 0; // количество шагов интегрирования
function setM(new_m) {m = new_m * m0;} function setC(new_C) {C = new_C * C0;} function setB(new_B) {B = new_B * B0;}
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 v = 0; // скорость тела
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 coil = 10; // количество витков var startX = 0; // закрепление пружины
// создаем прямоугольник-грузик var rect = { x: x0, width: rw, y: y0, height: rh, fill: "rgba(0, 0, 255, 1)" // цвет };
// захват прямоугольника мышью var mx_; // буфер позиции мыши (для расчета скорости при отпускании шара) document.onmousedown = function(e) { // функция при нажатии клавиши мыши var m = mouseCoords(e); // получаем расчетные координаты курсора мыши
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; }
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( // определить график "#vGraph", // на html-элементе #vGraph 250, // сколько шагов по оси "x" отображается -1, 1, 0.2); // мин. значение оси Y, макс. значение оси Y, шаг по оси Y
function control() { calculate(); draw(); requestAnimationFrame(control); } control();
// setInterval(control, 1000 / fps); // Запуск системы
function calculate() { if (!count) return; for (var s=1; s<=spf; s++) { var f = - C * (rect.x - x0) - B * v; v += f / m * dt; rect.x += v * dt;
steps++; if (steps % 80 == 0) vGraph.graphIter(steps, (rect.x-x0)/canvas.width*2); // подать данные на график }
}
function draw() { ctx.clearRect(0, 0, w, h);
ctx.strokeStyle = "#0aa"; ctx.beginPath(); ctx.moveTo(0, y0+rh/2); for (var i = 1; i <= coil + 1; i++ ) { 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); }
} </source> Файл "Spring.html" <syntaxhighlight lang="html" line start="1" enclose="div"> <!DOCTYPE html> <html> <head>
<meta charset="UTF-8" /> <title>Пружина</title> <script src="Spring.js"></script> <script src="jquery.min.js"></script> <script src="jquery.flot.js"></script> <script src="TM_v2-1.js"></script>
</head> <body>
<canvas id="spring_canvas" width="600" height="100" style="border:1px solid #000000;"></canvas>
<input type="range" id="slider_m" min="0.01" max="10" step=0.01 style="width: 150px;" /> m = <input type="number" id="number_m" min="0.01" max="10" step=0.01 style="width: 50px;" />
<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;" />
<input type="range" id="slider_B" min="0" max="10" step=0.01 style="width: 150px;" /> B = <input type="number" id="number_B" min="0" max="10" step=0.01 style="width: 50px;" />
x | |
steps |
</body> </html> </source> </toggledisplay>
Предлагаемые направления развития стенда
- Моделирование двумерной системы, в которой груз закреплен пружинами с четырех сторон.
- Моделирование более сложных конфигураций, например, несколько пружин подряд с разной жесткостью.
- Возможность определения, является ли система апериодичной при заданных условиях.