JavaScript-mechanics — различия между версиями
Материал из Department of Theoretical and Applied Mechanics
Денис (обсуждение | вклад) |
Wikiadmin (обсуждение | вклад) м (Замена текста — «</syntaxhighligh>» на «</syntaxhighlight>») |
||
(не показано 5 промежуточных версий 2 участников) | |||
Строка 7: | Строка 7: | ||
Левая клавиша мыши по полю - заморозить шарик. | Левая клавиша мыши по полю - заморозить шарик. | ||
− | + | ||
− | + | ||
− | + | ||
<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"''' | ||
− | < | + | <syntaxhighlight lang="javascript" line start="1" enclose="div"> |
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 | + | const k0 = 2 * Pi / T0; // масштаб частоты |
− | const | + | const C0 = m0 * k0 * k0; // масштаб жесткости |
− | const | + | const B0 = 2 * m0 * k0; // масштаб вязкости |
− | var count = true; | + | // *** Задание физических параметров *** |
+ | |||
+ | 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 странице | // создаем объект, связанный с элементом 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(); // функция, выполняющаяся на каждом шаге | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
</toggledisplay> | </toggledisplay> | ||
Строка 110: | Строка 127: | ||
*[[JavaScript-приложения]] | *[[JavaScript-приложения]] | ||
+ | [[Category: Виртуальная лаборатория]] | ||
[[Category: Программирование]] | [[Category: Программирование]] | ||
[[Category: JavaScript]] | [[Category: JavaScript]] |
Текущая версия на 13:55, 9 марта 2015
Кафедра ТМ > Программирование > Интернет > JavaScript > МеханикаЕсли у вас отображается старая версия программы - нажмите "Ctrl + F5"
Левая клавиша мыши по шарику - перетаскивание.
Левая клавиша мыши по полю - заморозить шарик.
Не удается найти HTML-файл mechanics_TM.html
Текст программы на языке JavaScript (разработчики Кривцов Антон, Цветков Денис, использована библиотека oCanvas): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> Файл "mechanics.js"
1 function MainMech(canvas) {
2
3 // Предварительные установки
4
5 var context = canvas.getContext("2d");
6
7 const Pi = 3.1415926; // число "пи"
8
9 const m0 = 1; // масштаб массы
10 const T0 = 1; // масштаб времени (период колебаний исходной системы)
11 const a0 = 1; // масштаб расстояния (диаметр шара)
12
13 const g0 = 2 * a0 / T0 / T0; // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
14
15 const k0 = 2 * Pi / T0; // масштаб частоты
16 const C0 = m0 * k0 * k0; // масштаб жесткости
17 const B0 = 2 * m0 * k0; // масштаб вязкости
18
19 // *** Задание физических параметров ***
20
21 const Ny = 5; // Число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
22 const m = 1 * m0; // масса
23 const C = 4 * C0; // жесткость
24 const B = 0.003 * B0; // вязкость среды
25 const B1 = 0.03 * B0; // вязкость на стенках
26 const mg = 1 * m * g0; // сила тяжести
27
28 // *** Задание вычислительных параметров ***
29
30 const fps = 4 * 29; // frames per second - число кадров в секунду (качечтво отображения)
31 const spf = 1000; // steps per frame - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета)
32 const dt = 0.01 * T0 / fps; // шаг интегрирования (качество расчета)
33
34 // Выполнение программы
35
36 var scale = canvas.height / Ny / a0;// масштабный коэффициент для перехода от расчетных к экранным координатам
37 var w = canvas.width / scale; // ширина окна в расчетных координатах
38 var h = canvas.height / scale; // высота окна в расчетных координатах
39 var r = a0 / 2; // радиус шара
40
41 var x = 4 * r; var y = h - r; // начальное положение шара
42
43 var count = true; // проводить ли расчет системы
44
45 // создаем объект, связанный с элементом canvas на html странице
46 var ocanvas = oCanvas.create({
47 canvas: "#canvasMech", // canvasMech - id объекта canvas на html странице
48 fps: fps // сколько кадров в секунду
49 });
50
51 // создаем шар
52 var arc = ocanvas.display.arc({
53 x: x * scale,
54 y: y * scale,
55 radius: r * scale,
56 end: 360, // круг 360 градусов
57 fill: "rgba(0, 0, 255, 1)" // цвет
58 }).add();
59
60 // захват шара мышью
61 var mx, my; // актуальная позиция мыши
62 arc.dragAndDrop({
63 changeZindex: true, // если много шариков - захваченный будет нарисован спереди
64 start: function () {
65 count = false; // на время захвата - отключить расчет
66 this.fill = "rgba(0, 0, 255, 0.5)"; // пока держим шарик - он полупрозрачен
67 mx = ocanvas.mouse.x; my = ocanvas.mouse.y;
68 },
69 move: function () {
70 x = arc.x / scale; y = arc.y / scale;
71 vx = .001*(ocanvas.mouse.x-mx)/dt/fps; vy = .001*(ocanvas.mouse.y-my)/dt/fps;
72 mx = ocanvas.mouse.x; my = ocanvas.mouse.y;
73 },
74 end: function () {
75 count = true;
76 this.fill = "rgba(0, 0, 255, 1)"; // отпускаем шарик - полупрозрачность убирается
77 }
78 });
79
80 ocanvas.bind("mousedown", function () {count = false;}); // заморозить фигуру при клике на поле
81
82 var fx = 0; var fy = mg; // сила, действующая на шар
83 var vx = 0; var vy = 0; // скорость
84
85 function physics(){ // то, что происходит каждый шаг времени
86
87 if (!count) return;
88 for (var s=1; s<=spf; s++) {
89
90 fx = - B * vx; fy = mg - B * vy;
91 if (y + r > h) { fy += -C * (y + r - h) - B1 * vy; }
92 if (y - r < 0) { fy += -C * (y - r) - B1 * vy;}
93 if (x + r > w) { fx += -C * (x + r - w) - B1 * vx; }
94 if (x - r < 0) { fx += -C * (x - r) - B1 * vx; }
95
96 vx += fx / m * dt; vy += fy / m * dt;
97 x += vx * dt; y += vy * dt;
98
99 arc.x = x * scale; arc.y = y * scale;
100 }
101 }
102
103 ocanvas.setLoop(physics).start(); // функция, выполняющаяся на каждом шаге
104 }
</toggledisplay>