Balls v2 — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Новая страница: «Кафедра ТМ > Программирование > [[Программирование и моделирование в Интернет|Интер...»)
 
Строка 1: Строка 1:
[[ТМ|Кафедра ТМ]] > [[Программирование]] > [[Программирование и моделирование в Интернет|Интернет]] > [[JavaScript-программирование|JavaScript]] > [[JavaScript - Balls|Balls]] > '''Balls v2''' <HR>
+
[[Виртуальная лаборатория]] > [[JavaScript - Balls|Balls]] > [[Balls v2]] <HR>
  
<addscript src=Balls_v2_release/>
+
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Tcvetkov/Balls/Balls_v2_release/Balls_v2_release.html |width=830 |height=630 |border=0 }}
<htmlet nocache="yes">Balls_v2_TM</htmlet>
 
  
  
Строка 9: Строка 8:
 
Файл '''"Balls_v2_release.js"'''
 
Файл '''"Balls_v2_release.js"'''
 
<source lang="javascript" first-line="1">
 
<source lang="javascript" first-line="1">
function MainBalls(canvas) {
+
window.addEventListener("load", MainBalls, true);
 +
function MainBalls() {
  
 
     // Предварительные установки
 
     // Предварительные установки
  
 +
    var canvas = canvasBalls;
 
     var context = canvas.getContext("2d");                  // на context происходит рисование
 
     var context = canvas.getContext("2d");                  // на context происходит рисование
 
     canvas.oncontextmenu = function (e) {return false;};    // блокировка контекстного меню
 
     canvas.oncontextmenu = function (e) {return false;};    // блокировка контекстного меню
  
     const Pi = 3.1415926;                  // число "пи"
+
     var Pi = 3.1415926;                  // число "пи"
  
     const m0 = 1;                          // масштаб массы
+
     var m0 = 1;                          // масштаб массы
     const T0 = 1;                          // масштаб времени (период колебаний исходной системы)
+
     var T0 = 1;                          // масштаб времени (период колебаний исходной системы)
     const a0 = 1;                          // масштаб расстояния (диаметр шара)
+
     var a0 = 1;                          // масштаб расстояния (диаметр шара)
  
     const g0 = a0 / T0 / T0;                // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
+
     var g0 = a0 / T0 / T0;                // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
     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;                // масштаб вязкости
  
 
     // *** Задание физических параметров ***
 
     // *** Задание физических параметров ***
  
     const Ny = 5;                          // число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
+
     var Ny = 5;                          // число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
     const m = 1 * m0;                      // масса
+
     var m = 1 * m0;                      // масса
     const Cwall = 10 * C0;                  // жесткость стен
+
     var Cwall = 10 * C0;                  // жесткость стен
     const B = 0.008 * B0;                  // вязкость среды
+
     var B = 0.008 * B0;                  // вязкость среды
     const B1 = 0.03 * B0;                  // вязкость на стенках
+
     var B1 = 0.03 * B0;                  // вязкость на стенках
     const mg = 0.25 * m * g0;              // сила тяжести
+
     var mg = 0.25 * m * g0;              // сила тяжести
     const r = 0.5 * a0;                    // радиус частицы в расчетных координатах
+
     var r = 0.5 * a0;                    // радиус частицы в расчетных координатах
  
 
     // *** Задание вычислительных параметров ***
 
     // *** Задание вычислительных параметров ***
  
     const fps = 50;                        // frames per second - число кадров в секунду (качечтво отображения)
+
     var fps = 50;                        // frames per second - число кадров в секунду (качечтво отображения)
     const spf = 100;                        // steps per frame  - число шагов интегрирования между кадрами (скорость расчета)
+
     var spf = 100;                        // steps per frame  - число шагов интегрирования между кадрами (скорость расчета)
     const dt  = 0.045 * T0 / fps;          // шаг интегрирования (качество расчета)
+
     var dt  = 0.045 * T0 / fps;          // шаг интегрирования (качество расчета)
  
 
     // Выполнение программы
 
     // Выполнение программы
  
     const scale = canvas.height / Ny / a0;  // масштабный коэффициент для перехода от расчетных к экранным координатам
+
     var scale = canvas.height / Ny / a0;  // масштабный коэффициент для перехода от расчетных к экранным координатам
     const r2 = r * r;                      // ___в целях оптимизации___
+
     var r2 = r * r;                      // ___в целях оптимизации___
  
 
     var w = canvas.width / scale;          // ширина окна в расчетных координатах
 
     var w = canvas.width / scale;          // ширина окна в расчетных координатах
Строка 157: Строка 158:
 
<body>
 
<body>
 
     <canvas id="canvasBalls" width="800" height="600" style="border:1px solid #000000;"></canvas>
 
     <canvas id="canvasBalls" width="800" height="600" style="border:1px solid #000000;"></canvas>
    <script type="text/javascript">MainBalls(document.getElementById('canvasBalls'));</script>
 
 
</body>
 
</body>
 
</html>
 
</html>
Строка 163: Строка 163:
 
</toggledisplay>
 
</toggledisplay>
  
 +
[[Category: Виртуальная лаборатория]]
 
[[Category: Программирование]]
 
[[Category: Программирование]]
[[Category: JavaScript]]
 

Версия 20:46, 5 ноября 2014

Виртуальная лаборатория > Balls > Balls v2


Скачать программу: Balls_v2_release.zip Текст программы на языке JavaScript (разработчики Кривцов Антон, Цветков Денис): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default"> Файл "Balls_v2_release.js"

window.addEventListener("load", MainBalls, true);
function MainBalls() {

    // Предварительные установки

    var canvas = canvasBalls;
    var context = canvas.getContext("2d");                  // на context происходит рисование
    canvas.oncontextmenu = function (e) {return false;};    // блокировка контекстного меню

    var Pi = 3.1415926;                   // число "пи"

    var m0 = 1;                           // масштаб массы
    var T0 = 1;                           // масштаб времени (период колебаний исходной системы)
    var a0 = 1;                           // масштаб расстояния (диаметр шара)

    var g0 = a0 / T0 / T0;                // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
    var k0 = 2 * Pi / T0;                 // масштаб частоты
    var C0 = m0 * k0 * k0;                // масштаб жесткости
    var B0 = 2 * m0 * k0;                 // масштаб вязкости

    // *** Задание физических параметров ***

    var Ny = 5;                           // число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
    var m = 1 * m0;                       // масса
    var Cwall = 10 * C0;                  // жесткость стен
    var B = 0.008 * B0;                   // вязкость среды
    var B1 = 0.03 * B0;                   // вязкость на стенках
    var mg = 0.25 * m * g0;               // сила тяжести
    var r = 0.5 * a0;                     // радиус частицы в расчетных координатах

    // *** Задание вычислительных параметров ***

    var fps = 50;                         // frames per second - число кадров в секунду (качечтво отображения)
    var spf = 100;                        // steps per frame   - число шагов интегрирования между кадрами (скорость расчета)
    var dt  = 0.045 * T0 / fps;           // шаг интегрирования (качество расчета)

    // Выполнение программы

    var scale = canvas.height / Ny / a0;  // масштабный коэффициент для перехода от расчетных к экранным координатам
    var r2 = r * r;                       // ___в целях оптимизации___

    var w = canvas.width / scale;           // ширина окна в расчетных координатах
    var h = canvas.height / scale;          // высота окна в расчетных координатах

    var dNd = null;                         // ссылка на захваченный курсором шар (drag & drop)

    // Работа с мышью

    var mx_, my_;                           // буфер позиции мыши (для расчета скорости при отпускании шара)

    canvas.onmousedown = function(e) {      // функция при нажатии клавиши мыши
        var m = mouseCoords(e);             // получаем расчетные координаты курсора мыши
        var rx = b.x - m.x;
        var ry = b.y - m.y;
        var rLen2 = rx * rx + ry * ry;      // квадрат расстояния между курсором и центром шара
        if (rLen2 <= r2) {                  // курсор нажал на шар
            dNd = b;
            dNd.xPlus = dNd.x - m.x;        // сдвиг курсора относительно центра шара по x
            dNd.yPlus = dNd.y - m.y;        // сдвиг курсора относительно центра шара по y
            mx_ = m.x;    my_ = m.y;
            canvas.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения
        }
    };

    document.onmouseup = function(e) {          // функция при отпускании клавиши мыши
        canvas.onmousemove = null;              // когда клавиша отпущена - функции перемещения нету
        dNd = null;                             // когда клавиша отпущена - захваченного курсором шара нету
    };

    function mouseMove(e) {                     // функция при перемещении мыши, работает только с зажатой ЛКМ
        var m = mouseCoords(e);                 // получаем расчетные координаты курсора мыши
        dNd.x = m.x + dNd.xPlus;
        dNd.y = m.y + dNd.yPlus;
        dNd.vx = 0.6 * (m.x - mx_) / dt / fps;   dNd.vy = 0.6 * (m.y - my_) / dt / fps;
        mx_ = m.x;    my_ = m.y;
    }

    function mouseCoords(e) {                   // функция возвращает расчетные координаты курсора мыши
        var m = [];
        var rect = canvas.getBoundingClientRect();
        m.x = (e.clientX - rect.left) / scale;
        m.y = (e.clientY - rect.top) / scale;
        return m;
    }

    // Добавление шара

    var b = [];
    b.x = w / 2;            b.y = h / 2;        // расчетные координаты шара
    b.fx = 0;               b.fy = mg;          // сила, действующая на шар
    b.vx = 0;               b.vy = 0;           // скорость

    // Основной цикл программы

    function control() {
        physics();
        draw();
    }

    // Расчетная часть программы

    function physics() {                        // то, что происходит каждый шаг времени
        for (var s = 1; s <= spf; s++) {
            if (b == dNd) continue;             // если шар схвачен курсором - его вз. со стенами и перемещение не считаем

            b.fx = - B * b.vx;
            b.fy = mg - B * b.vy;

            if (b.y + r > h) { b.fy += -Cwall * (b.y + r - h) - B1 * b.vy; }
            if (b.y - r < 0) { b.fy += -Cwall * (b.y - r) - B1 * b.vy;}
            if (b.x + r > w) { b.fx += -Cwall * (b.x + r - w) - B1 * b.vx; }
            if (b.x - r < 0) { b.fx += -Cwall * (b.x - r) - B1 * b.vx; }

            b.vx += b.fx / m * dt;        b.vy += b.fy / m * dt;
            b.x += b.vx * dt;             b.y += b.vy * dt;
        }
    }

    // Рисование

    var rScale13 = r * scale * 1.3;         // ___в целях оптимизации___
    var rScaleShift = r * scale / 5;        // ___в целях оптимизации___
    function draw() {
        context.clearRect(0, 0, w * scale, h * scale);      // очистить экран
            var xS = b.x * scale;           var yS = b.y * scale;
            var gradient = context.createRadialGradient(xS, yS, rScale13, xS - rScaleShift, yS + rScaleShift, 0);
            gradient.addColorStop(0, "#0000bb");
            gradient.addColorStop(1, "#44ddff");
            context.fillStyle = gradient;

            context.beginPath();
            context.arc(xS, yS, r * scale, 0, 2 * Math.PI, false);
            context.closePath();
            context.fill();
    }

    // Запуск системы
    setInterval(control, 1000 / fps);
}

Файл "Balls_v2_release.html"

<!DOCTYPE html>
<html>
<head>
    <title>Balls</title>
    <script src="Balls_v2_release.js"></script>
</head>
<body>
    <canvas id="canvasBalls" width="800" height="600" style="border:1px solid #000000;"></canvas>
</body>
</html>

</toggledisplay>