JavaScript-mechanics — различия между версиями
Материал из Department of Theoretical and Applied Mechanics
Денис (обсуждение | вклад) |
Денис (обсуждение | вклад) |
||
Строка 12: | Строка 12: | ||
<htmlet nocache="yes">mechanics_TM</htmlet> | <htmlet nocache="yes">mechanics_TM</htmlet> | ||
− | Текст программы на языке JavaScript ( | + | Текст программы на языке JavaScript (разработчики [[Кривцов Антон]], [[Цветков Денис]], использована библиотека [http://ocanvas.org/ oCanvas]): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> |
Файл '''"mechanics.js"''' | Файл '''"mechanics.js"''' | ||
<source lang="javascript" first-line="1"> | <source lang="javascript" first-line="1"> | ||
function MainMech(canvas) { | function MainMech(canvas) { | ||
+ | |||
+ | // Предварительные установки | ||
+ | |||
var context = canvas.getContext("2d"); | var context = canvas.getContext("2d"); | ||
− | |||
− | |||
− | const | + | const Pi = 3.1415926; // число "пи" |
− | const | + | |
− | const | + | const m0 = 1; // масштаб массы |
− | const | + | const T0 = 1; // масштаб времени (период колебаний исходной системы) |
+ | const a0 = 1; // масштаб расстояния (диаметр шара) | ||
+ | |||
+ | const g0 = 2 * a0 / T0 / T0; // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0) | ||
+ | |||
+ | const k0 = 2 * Pi / T0; // масштаб частоты | ||
+ | const C0 = m0 * k0 * k0; // масштаб жесткости | ||
+ | const B0 = 2 * m0 * k0; // масштаб вязкости | ||
+ | |||
+ | // *** Задание физических параметров *** | ||
+ | |||
+ | const Ny = 5; // Число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна) | ||
+ | const m = 1 * m0; // масса | ||
+ | const C = 4 * C0; // жесткость | ||
+ | const B = 0.003 * B0; // вязкость среды | ||
+ | const B1 = 0.03 * B0; // вязкость на стенках | ||
+ | const mg = 1 * m * g0; // сила тяжести | ||
+ | |||
+ | // *** Задание вычислительных параметров *** | ||
+ | |||
+ | const fps = 4 * 29; // frames per second - число кадров в секунду (качечтво отображения) | ||
+ | const spf = 1000; // steps per frame - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета) | ||
+ | const dt = 0.01 * T0 / fps; // шаг интегрирования (качество расчета) | ||
+ | |||
+ | // Выполнение программы | ||
+ | |||
+ | var scale = canvas.height / Ny / a0;// масштабный коэффициент для перехода от расчетных к экранным координатам | ||
+ | var w = canvas.width / scale; // ширина окна в расчетных координатах | ||
+ | var h = canvas.height / scale; // высота окна в расчетных координатах | ||
+ | var r = a0 / 2; // радиус шара | ||
− | + | var x = 4 * r; var y = h - r; // начальное положение шара | |
− | |||
− | |||
− | var count = true; | + | var count = true; // проводить ли расчет системы |
// создаем объект, связанный с элементом canvas на html странице | // создаем объект, связанный с элементом canvas на html странице | ||
var ocanvas = oCanvas.create({ | var ocanvas = oCanvas.create({ | ||
− | canvas: "#canvasMech", | + | canvas: "#canvasMech", // canvasMech - id объекта canvas на html странице |
− | fps: | + | fps: fps // сколько кадров в секунду |
}); | }); | ||
// создаем шар | // создаем шар | ||
var arc = ocanvas.display.arc({ | var arc = ocanvas.display.arc({ | ||
− | x: | + | x: x * scale, |
− | y: | + | y: y * scale, |
− | radius: r, | + | radius: r * scale, |
end: 360, // круг 360 градусов | end: 360, // круг 360 градусов | ||
fill: "rgba(0, 0, 255, 1)" // цвет | fill: "rgba(0, 0, 255, 1)" // цвет | ||
Строка 47: | Строка 75: | ||
// захват шара мышью | // захват шара мышью | ||
− | + | var mx, my; // актуальная позиция мыши | |
− | var mx | ||
arc.dragAndDrop({ | arc.dragAndDrop({ | ||
− | changeZindex: true, | + | changeZindex: true, // если много шариков - захваченный будет нарисован спереди |
start: function () { | start: function () { | ||
− | count = false; | + | count = false; // на время захвата - отключить расчет |
− | this.fill = "rgba(0, 0, 255, 0.5)"; | + | this.fill = "rgba(0, 0, 255, 0.5)"; // пока держим шарик - он полупрозрачен |
− | + | mx = ocanvas.mouse.x; my = ocanvas.mouse.y; | |
− | |||
}, | }, | ||
move: function () { | move: function () { | ||
− | + | x = arc.x / scale; y = arc.y / scale; | |
− | + | vx = .001*(ocanvas.mouse.x-mx)/dt/fps; vy = .001*(ocanvas.mouse.y-my)/dt/fps; | |
− | + | mx = ocanvas.mouse.x; my = ocanvas.mouse.y; | |
}, | }, | ||
end: function () { | end: function () { | ||
count = true; | count = true; | ||
this.fill = "rgba(0, 0, 255, 1)"; // отпускаем шарик - полупрозрачность убирается | this.fill = "rgba(0, 0, 255, 1)"; // отпускаем шарик - полупрозрачность убирается | ||
− | + | } | |
− | |||
− | |||
− | |||
}); | }); | ||
+ | |||
ocanvas.bind("mousedown", function () {count = false;}); // заморозить фигуру при клике на поле | ocanvas.bind("mousedown", function () {count = false;}); // заморозить фигуру при клике на поле | ||
− | var | + | var fx = 0; var fy = mg; // сила, действующая на шар |
− | var vx = 0; | + | var vx = 0; var vy = 0; // скорость |
+ | |||
function physics(){ // то, что происходит каждый шаг времени | function physics(){ // то, что происходит каждый шаг времени | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | if (!count) return; | |
− | + | for (var s=1; s<=spf; s++) { | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | fx = - B * vx; fy = mg - B * vy; | |
− | + | if (y + r > h) { fy += -C * (y + r - h) - B1 * vy; } | |
− | + | if (y - r < 0) { fy += -C * (y - r) - B1 * vy;} | |
− | + | if (x + r > w) { fx += -C * (x + r - w) - B1 * vx; } | |
− | + | if (x - r < 0) { fx += -C * (x - r) - B1 * vx; } | |
− | + | ||
− | + | vx += fx / m * dt; vy += fy / m * dt; | |
− | + | x += vx * dt; y += vy * dt; | |
+ | |||
+ | arc.x = x * scale; arc.y = y * scale; | ||
+ | } | ||
} | } | ||
+ | |||
ocanvas.setLoop(physics).start(); // функция, выполняющаяся на каждом шаге | ocanvas.setLoop(physics).start(); // функция, выполняющаяся на каждом шаге | ||
} | } |
Версия 04:24, 12 марта 2014
Кафедра ТМ > Программирование > Интернет > JavaScript > МеханикаЕсли у вас отображается старая версия программы - нажмите "Ctrl + F5"
Левая клавиша мыши по шарику - перетаскивание.
Левая клавиша мыши по полю - заморозить шарик. <addscript src=ocanvas-251/> <addscript src=Vector2D/> <addscript src=mechanics/>
Не удается найти HTML-файл mechanics_TM.html
Текст программы на языке JavaScript (разработчики Кривцов Антон, Цветков Денис, использована библиотека oCanvas): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> Файл "mechanics.js"
function MainMech(canvas) {
// Предварительные установки
var context = canvas.getContext("2d");
const Pi = 3.1415926; // число "пи"
const m0 = 1; // масштаб массы
const T0 = 1; // масштаб времени (период колебаний исходной системы)
const a0 = 1; // масштаб расстояния (диаметр шара)
const g0 = 2 * a0 / T0 / T0; // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
const k0 = 2 * Pi / T0; // масштаб частоты
const C0 = m0 * k0 * k0; // масштаб жесткости
const B0 = 2 * m0 * k0; // масштаб вязкости
// *** Задание физических параметров ***
const Ny = 5; // Число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
const m = 1 * m0; // масса
const C = 4 * C0; // жесткость
const B = 0.003 * B0; // вязкость среды
const B1 = 0.03 * B0; // вязкость на стенках
const mg = 1 * m * g0; // сила тяжести
// *** Задание вычислительных параметров ***
const fps = 4 * 29; // frames per second - число кадров в секунду (качечтво отображения)
const spf = 1000; // steps per frame - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета)
const dt = 0.01 * T0 / fps; // шаг интегрирования (качество расчета)
// Выполнение программы
var scale = canvas.height / Ny / a0;// масштабный коэффициент для перехода от расчетных к экранным координатам
var w = canvas.width / scale; // ширина окна в расчетных координатах
var h = canvas.height / scale; // высота окна в расчетных координатах
var r = a0 / 2; // радиус шара
var x = 4 * r; var y = h - r; // начальное положение шара
var count = true; // проводить ли расчет системы
// создаем объект, связанный с элементом canvas на html странице
var ocanvas = oCanvas.create({
canvas: "#canvasMech", // canvasMech - id объекта canvas на html странице
fps: fps // сколько кадров в секунду
});
// создаем шар
var arc = ocanvas.display.arc({
x: x * scale,
y: y * scale,
radius: r * scale,
end: 360, // круг 360 градусов
fill: "rgba(0, 0, 255, 1)" // цвет
}).add();
// захват шара мышью
var mx, my; // актуальная позиция мыши
arc.dragAndDrop({
changeZindex: true, // если много шариков - захваченный будет нарисован спереди
start: function () {
count = false; // на время захвата - отключить расчет
this.fill = "rgba(0, 0, 255, 0.5)"; // пока держим шарик - он полупрозрачен
mx = ocanvas.mouse.x; my = ocanvas.mouse.y;
},
move: function () {
x = arc.x / scale; y = arc.y / scale;
vx = .001*(ocanvas.mouse.x-mx)/dt/fps; vy = .001*(ocanvas.mouse.y-my)/dt/fps;
mx = ocanvas.mouse.x; my = ocanvas.mouse.y;
},
end: function () {
count = true;
this.fill = "rgba(0, 0, 255, 1)"; // отпускаем шарик - полупрозрачность убирается
}
});
ocanvas.bind("mousedown", function () {count = false;}); // заморозить фигуру при клике на поле
var fx = 0; var fy = mg; // сила, действующая на шар
var vx = 0; var vy = 0; // скорость
function physics(){ // то, что происходит каждый шаг времени
if (!count) return;
for (var s=1; s<=spf; s++) {
fx = - B * vx; fy = mg - B * vy;
if (y + r > h) { fy += -C * (y + r - h) - B1 * vy; }
if (y - r < 0) { fy += -C * (y - r) - B1 * vy;}
if (x + r > w) { fx += -C * (x + r - w) - B1 * vx; }
if (x - r < 0) { fx += -C * (x - r) - B1 * vx; }
vx += fx / m * dt; vy += fy / m * dt;
x += vx * dt; y += vy * dt;
arc.x = x * scale; arc.y = y * scale;
}
}
ocanvas.setLoop(physics).start(); // функция, выполняющаяся на каждом шаге
}
</toggledisplay>