Balls v2

Материал из Department of Theoretical and Applied Mechanics
Версия от 08:50, 11 марта 2015; Денис (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск
Виртуальная лаборатория > Динамика взаимодействующих частиц > Balls - версии > Balls v2


Скачать программу: Balls_v2_release.zip

Текст программы на языке JavaScript (разработчики Кривцов Антон, Цветков Денис):

Файл "Balls_v2_release.js"

  1 window.addEventListener("load", MainBalls, true);
  2 function MainBalls() {
  3 
  4     // Предварительные установки
  5 
  6     var canvas = canvasBalls;
  7     var context = canvas.getContext("2d");                  // на context происходит рисование
  8     canvas.oncontextmenu = function (e) {return false;};    // блокировка контекстного меню
  9 
 10     var Pi = 3.1415926;                   // число "пи"
 11 
 12     var m0 = 1;                           // масштаб массы
 13     var T0 = 1;                           // масштаб времени (период колебаний исходной системы)
 14     var a0 = 1;                           // масштаб расстояния (диаметр шара)
 15 
 16     var g0 = a0 / T0 / T0;                // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
 17     var k0 = 2 * Pi / T0;                 // масштаб частоты
 18     var C0 = m0 * k0 * k0;                // масштаб жесткости
 19     var B0 = 2 * m0 * k0;                 // масштаб вязкости
 20 
 21     // *** Задание физических параметров ***
 22 
 23     var Ny = 5;                           // число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
 24     var m = 1 * m0;                       // масса
 25     var Cwall = 10 * C0;                  // жесткость стен
 26     var B = 0.008 * B0;                   // вязкость среды
 27     var B1 = 0.03 * B0;                   // вязкость на стенках
 28     var mg = 0.25 * m * g0;               // сила тяжести
 29     var r = 0.5 * a0;                     // радиус частицы в расчетных координатах
 30 
 31     // *** Задание вычислительных параметров ***
 32 
 33     var fps = 50;                         // frames per second - число кадров в секунду (качечтво отображения)
 34     var spf = 100;                        // steps per frame   - число шагов интегрирования между кадрами (скорость расчета)
 35     var dt  = 0.045 * T0 / fps;           // шаг интегрирования (качество расчета)
 36 
 37     // Выполнение программы
 38 
 39     var scale = canvas.height / Ny / a0;  // масштабный коэффициент для перехода от расчетных к экранным координатам
 40     var r2 = r * r;                       // ___в целях оптимизации___
 41 
 42     var w = canvas.width / scale;           // ширина окна в расчетных координатах
 43     var h = canvas.height / scale;          // высота окна в расчетных координатах
 44 
 45     var dNd = null;                         // ссылка на захваченный курсором шар (drag & drop)
 46 
 47     // Работа с мышью
 48 
 49     var mx_, my_;                           // буфер позиции мыши (для расчета скорости при отпускании шара)
 50 
 51     canvas.onmousedown = function(e) {      // функция при нажатии клавиши мыши
 52         var m = mouseCoords(e);             // получаем расчетные координаты курсора мыши
 53         var rx = b.x - m.x;
 54         var ry = b.y - m.y;
 55         var rLen2 = rx * rx + ry * ry;      // квадрат расстояния между курсором и центром шара
 56         if (rLen2 <= r2) {                  // курсор нажал на шар
 57             dNd = b;
 58             dNd.xPlus = dNd.x - m.x;        // сдвиг курсора относительно центра шара по x
 59             dNd.yPlus = dNd.y - m.y;        // сдвиг курсора относительно центра шара по y
 60             mx_ = m.x;    my_ = m.y;
 61             canvas.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения
 62         }
 63     };
 64 
 65     document.onmouseup = function(e) {          // функция при отпускании клавиши мыши
 66         canvas.onmousemove = null;              // когда клавиша отпущена - функции перемещения нету
 67         dNd = null;                             // когда клавиша отпущена - захваченного курсором шара нету
 68     };
 69 
 70     function mouseMove(e) {                     // функция при перемещении мыши, работает только с зажатой ЛКМ
 71         var m = mouseCoords(e);                 // получаем расчетные координаты курсора мыши
 72         dNd.x = m.x + dNd.xPlus;
 73         dNd.y = m.y + dNd.yPlus;
 74         dNd.vx = 0.6 * (m.x - mx_) / dt / fps;   dNd.vy = 0.6 * (m.y - my_) / dt / fps;
 75         mx_ = m.x;    my_ = m.y;
 76     }
 77 
 78     function mouseCoords(e) {                   // функция возвращает расчетные координаты курсора мыши
 79         var m = [];
 80         var rect = canvas.getBoundingClientRect();
 81         m.x = (e.clientX - rect.left) / scale;
 82         m.y = (e.clientY - rect.top) / scale;
 83         return m;
 84     }
 85 
 86     // Добавление шара
 87 
 88     var b = [];
 89     b.x = w / 2;            b.y = h / 2;        // расчетные координаты шара
 90     b.fx = 0;               b.fy = mg;          // сила, действующая на шар
 91     b.vx = 0;               b.vy = 0;           // скорость
 92 
 93     // Основной цикл программы
 94 
 95     function control() {
 96         physics();
 97         draw();
 98     }
 99 
100     // Расчетная часть программы
101 
102     function physics() {                        // то, что происходит каждый шаг времени
103         for (var s = 1; s <= spf; s++) {
104             if (b == dNd) continue;             // если шар схвачен курсором - его вз. со стенами и перемещение не считаем
105 
106             b.fx = - B * b.vx;
107             b.fy = mg - B * b.vy;
108 
109             if (b.y + r > h) { b.fy += -Cwall * (b.y + r - h) - B1 * b.vy; }
110             if (b.y - r < 0) { b.fy += -Cwall * (b.y - r) - B1 * b.vy;}
111             if (b.x + r > w) { b.fx += -Cwall * (b.x + r - w) - B1 * b.vx; }
112             if (b.x - r < 0) { b.fx += -Cwall * (b.x - r) - B1 * b.vx; }
113 
114             b.vx += b.fx / m * dt;        b.vy += b.fy / m * dt;
115             b.x += b.vx * dt;             b.y += b.vy * dt;
116         }
117     }
118 
119     // Рисование
120 
121     var rScale13 = r * scale * 1.3;         // ___в целях оптимизации___
122     var rScaleShift = r * scale / 5;        // ___в целях оптимизации___
123     function draw() {
124         context.clearRect(0, 0, w * scale, h * scale);      // очистить экран
125             var xS = b.x * scale;           var yS = b.y * scale;
126             var gradient = context.createRadialGradient(xS, yS, rScale13, xS - rScaleShift, yS + rScaleShift, 0);
127             gradient.addColorStop(0, "#0000bb");
128             gradient.addColorStop(1, "#44ddff");
129             context.fillStyle = gradient;
130 
131             context.beginPath();
132             context.arc(xS, yS, r * scale, 0, 2 * Math.PI, false);
133             context.closePath();
134             context.fill();
135     }
136 
137     // Запуск системы
138     setInterval(control, 1000 / fps);
139 }

Файл "Balls_v2_release.html"

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>Balls</title>
 5     <script src="Balls_v2_release.js"></script>
 6 </head>
 7 <body>
 8     <canvas id="canvasBalls" width="800" height="600" style="border:1px solid #000000;"></canvas>
 9 </body>
10 </html>