Редактирование: JavaScript-mechanics

Перейти к: навигация, поиск

Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.

Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
[[ТМ|Кафедра ТМ]] > [[Программирование]] > [[Программирование и моделирование в Интернет|Интернет]] > [[JavaScript-программирование|JavaScript]] > '''Механика''' <HR>
+
См. также [[JavaScript-mechanics-box2D]]
 +
<addscript src=ocanvas-251/>
 +
<addscript src=Vector2D/>
 +
<addscript src=mechanics/>
 +
<htmlet nocache="yes">mechanics_TM</htmlet>
  
Если у вас отображается старая версия программы - нажмите "'''Ctrl + F5'''"
 
  
 +
Текст программы на языке JavaScript (разработчик [[Цветков Денис]], использована библиотека [http://ocanvas.org/ oCanvas]): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default">
 +
Файл '''"mechanics.js"'''
 +
<source lang="javascript" first-line="1">
 +
function MainMech(canvas) {
 +
    var context = canvas.getContext("2d");
  
Левая клавиша мыши по шарику - перетаскивание.
+
    var w = canvas.width;
 +
    var h = canvas.height;
  
Левая клавиша мыши по полю - заморозить шарик.
+
    var r = w  / 50;
  
 +
    var ocanvas = oCanvas.create({
 +
        canvas: "#canvasMech",
 +
        fps: 60
 +
    });
 +
 +
    var arc = ocanvas.display.arc({
 +
        x: 4*r,
 +
        y: h,
 +
        radius: r,
 +
        start: 0,
 +
        end: 360,
 +
        fill: "rgba(0, 0, 255, 1)"
 +
    }).add();
  
 +
    var m0 = new Vector2D(0, 0);
 +
    var m = new Vector2D(0, 0);
 +
    arc.dragAndDrop({
 +
        changeZindex: true,
 +
        start: function ()  {
 +
            this.fill = "rgba(0, 0, 255, 0.5)";
 +
            count = false;
 +
            m0.set(0, 0);
 +
            m.set(0, 0);
 +
        },
 +
        move: function ()  {
 +
            m0.set(m);
 +
            m.set(ocanvas.mouse.x, ocanvas.mouse.y);
 +
        },
 +
        end: function ()    {
 +
            this.fill = "rgba(0, 0, 255, 1)";
 +
            count = true;
 +
            v.x = (m.x-m0.x)*100; v.y = (m.y-m0.y)*100;
 +
        }
 +
    });
  
<htmlet nocache="yes">mechanics_TM</htmlet>
+
    ocanvas.setLoop(physics).start();
  
Текст программы на языке JavaScript (разработчики [[Кривцов Антон]], [[Цветков Денис]], использована библиотека [http://ocanvas.org/ oCanvas]): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default">
+
    // границы:
Файл '''"mechanics.js"'''
+
    const xb0 = 0;
<syntaxhighlight lang="javascript" line start="1" enclose="div">
+
    const xb1 = w;
function MainMech(canvas) {
+
    const yb0 = 0;
 +
    const yb1 = h;
  
     // Предварительные установки   
+
     const g = 9.8*2000;      // 9.8 px, а не метров
 +
    const dt = 1/60;
 +
    const elastKoeff = 0.9;  // коэффициент упругости
 +
    var count = true;
  
     var context = canvas.getContext("2d");
+
     var a = new Vector2D(0, 0);
 +
    var v = new Vector2D(0, 0);
  
    const Pi = 3.1415926;          // число "пи"   
 
  
     const m0 = 1;                   // масштаб массы
+
     function physics(){ // то, что происходит каждый шаг времени
    const T0 = 1;                   // масштаб времени (период колебаний исходной системы)
+
        const arcD = arc.y + r;
    const a0 = 1;                   // масштаб расстояния (диаметр шара)
+
        const arcU = arc.y - r;
 +
        const arcL = arc.x - r;
 +
        const arcR = arc.x + r;
  
    const g0 = 2 * a0 / T0 / T0;    // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
+
        var dr = new Vector2D(0, 0);
  
    const k0 = 2 * Pi / T0;           // масштаб частоты
+
        a.set(0, g);
    const C0 = m0 * k0 * k0;         // масштаб жесткости
+
        v = v.add(a.multiple(dt));
    const B0 = 2 * m0 * k0;       // масштаб вязкости
+
        dr.set(v.multiple(dt));
  
    // *** Задание физических параметров ***
 
  
    const Ny = 5; // Число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
+
        // проверка граничных условий
    const m = 1 * m0;                 // масса
+
        if (arcD + dr.y > h) {
    const C = 4 * C0;                 // жесткость
+
            v.y = -Math.abs(v.y)*elastKoeff;
    const B = 0.003 * B0;             // вязкость среды
+
            if (count) arc.y = h - r;
    const B1 = 0.03 * B0;             // вязкость на стенках
+
            dr.y = -Math.abs(h - arcD);
    const mg = 1 * m * g0;         // сила тяжести
+
        }
   
+
        if (arcU + dr.y < 0) {
    // *** Задание вычислительных параметров ***
+
            v.y = Math.abs(v.y)*elastKoeff;
 +
            if (count) arc.y = r;
 +
            dr.y = Math.abs(arcU);
 +
        }
 +
        if (arcR + dr.x > w) {
 +
            v.x = -Math.abs(v.x)*elastKoeff;
 +
            if (count) arc.x = w - r;
 +
            dr.x = -Math.abs(w - arcR);
 +
        }
 +
        if (arcL + dr.x < 0) {
 +
            v.x = Math.abs(v.x)*elastKoeff;
 +
            if (count) arc.x = r;
 +
            dr.x = Math.abs(arcL);
 +
        }
  
     const fps = 4 * 29;             // frames per second - число кадров в секунду (качечтво отображения)
+
        if (count) {arc.x += dr.x;     arc.y += dr.y;}
     const spf = 1000;              // steps per frame  - число шагов интегрирования между кадрами (edtkbxbdftn скорость расчета)
+
    }
     const dt  = 0.01 * T0 / fps;     // шаг интегрирования (качество расчета)
+
}
 +
</source>
 +
Файл '''"mechanics.html"'''
 +
<source lang="html" first-line="1">
 +
<!DOCTYPE html>
 +
<html>
 +
<head>
 +
    <title>Simple Mechanics</title>
 +
     <script src="http://cdnjs.cloudflare.com/ajax/libs/ocanvas/2.5.1/ocanvas.min.js"></script>
 +
    <script src="Vector2D.js"></script>
 +
     <script src="mechanics.js"></script>
 +
</head>
 +
<body>
 +
    <canvas id="canvasMech" width="800" height="600" style="border:1px solid #000000;"></canvas>
 +
    <script type="text/javascript">MainMech(document.getElementById('canvasMech'));</script>
 +
</body>
 +
</html>
 +
</source>
 +
</toggledisplay>
  
    // Выполнение программы
 
  
    var scale = canvas.height / Ny / a0;// масштабный коэффициент для перехода от расчетных к экранным координатам
+
Старая версия (без векторов): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default">
    var w = canvas.width / scale; // ширина окна в расчетных координатах
+
Файл '''"mechanics.js"'''
     var h = canvas.height / scale; // высота окна в расчетных координатах
+
<source lang="javascript" first-line="1">
    var r = a0 / 2;               // радиус шара
+
function MainMech(canvas) {
 +
     var context = canvas.getContext("2d");
  
     var x = 4 * r; var y = h - r; // начальное положение шара
+
     var w = canvas.width;
 +
    var h = canvas.height;
  
     var count = true;                 // проводить ли расчет системы
+
     var r = w  / 50;
  
    // создаем объект, связанный с элементом canvas на html странице
 
 
     var ocanvas = oCanvas.create({
 
     var ocanvas = oCanvas.create({
         canvas: "#canvasMech",       // canvasMech - id объекта canvas на html странице
+
         canvas: "#canvasMech",
         fps: fps                        // сколько кадров в секунду
+
         fps: 60
 
     });
 
     });
  
    // создаем шар
 
 
     var arc = ocanvas.display.arc({
 
     var arc = ocanvas.display.arc({
         x: x * scale,
+
         x: 4*r,
         y: y * scale,
+
         y: h,
         radius: r * scale,
+
         radius: r,
         end: 360,                     // круг 360 градусов
+
        start: 0,
         fill: "rgba(0, 0, 255, 1)"   // цвет
+
         end: 360,
 +
         fill: "rgba(0, 0, 255, 1)"
 
     }).add();
 
     }).add();
  
     // захват шара мышью
+
     var m0x = 0; var m0y = 0;
     var mx, my;       // актуальная позиция мыши
+
     var mx = 0;  var my = 0;
 
     arc.dragAndDrop({
 
     arc.dragAndDrop({
         changeZindex: true,           // если много шариков - захваченный будет нарисован спереди
+
         changeZindex: true,
 
         start: function ()  {
 
         start: function ()  {
            count = false;            // на время захвата - отключить расчет
+
             this.fill = "rgba(0, 0, 255, 0.5)";
             this.fill = "rgba(0, 0, 255, 0.5)";     // пока держим шарик - он полупрозрачен
+
            count = false;
        mx = ocanvas.mouse.x;   my = ocanvas.mouse.y;
+
            m0x = 0; m0y = 0;
 +
            mx = 0; my = 0;
 
         },
 
         },
 
         move: function ()  {
 
         move: function ()  {
x = arc.x / scale;    y = arc.y / scale;
+
            m0x = mx; m0y = my;
        vx = .001*(ocanvas.mouse.x-mx)/dt/fps;   vy = .001*(ocanvas.mouse.y-my)/dt/fps;
+
            mx = ocanvas.mouse.x;
        mx = ocanvas.mouse.x;                   my = ocanvas.mouse.y;
+
            my = ocanvas.mouse.y;
 
         },
 
         },
 
         end: function ()    {
 
         end: function ()    {
 +
            this.fill = "rgba(0, 0, 255, 1)";
 
             count = true;
 
             count = true;
             this.fill = "rgba(0, 0, 255, 1)";       // отпускаем шарик - полупрозрачность убирается
+
             vx = (mx-m0x)*100; vy = (my-m0y)*100;
      }
+
        }
 
     });
 
     });
   
 
    ocanvas.bind("mousedown", function () {count = false;});    // заморозить фигуру при клике на поле
 
  
     var fx = 0;           var fy = mg;             // сила, действующая на шар
+
     ocanvas.setLoop(physics).start();
     var vx = 0;           var vy = 0;             // скорость
+
 
 +
    // границы:
 +
    const xb0 = 0;
 +
    const xb1 = w;
 +
    const yb0 = 0;
 +
    const yb1 = h;
 +
 
 +
    const g = 9.8*2000;     // 9.8 px, а не метров
 +
    const dt = 1/60;
 +
    const elastKoeff = 0.9;  // коэффициент упругости
 +
    var count = true;
 +
    var ax = 0;
 +
    var ay = 0;
 +
     var vx = 2;
 +
    var vy = 0;
 +
 
 +
 
 +
    function physics(){ // то, что происходит каждый шаг времени
 +
        const arcD = arc.y + r;
 +
        const arcU = arc.y - r;
 +
        const arcL = arc.x - r;
 +
        const arcR = arc.x + r;
 +
 
 +
        var dx = 0;
 +
        var dy = 0;
  
    function physics(){                            // то, что происходит каждый шаг времени
+
        ax = 0;            ay = g;
 +
        vx += ax*dt;        vy += ay*dt;
 +
        dx = vx*dt;        dy = vy*dt;
  
if (!count) return;
+
        // проверка граничных условий
    for (var s=1; s<=spf; s++) {
+
        if (arcD + dy > h) {
 +
            vy = -Math.abs(vy)*elastKoeff;
 +
            if (count) arc.y = h - r;
 +
            dy = -Math.abs(h - arcD);
 +
        }
 +
        if (arcU + dy < 0) {
 +
            vy = Math.abs(vy)*elastKoeff;
 +
            if (count) arc.y = r;
 +
            dy = Math.abs(arcU);
 +
        }
 +
        if (arcR + dx > w) {
 +
            vx = -Math.abs(vx)*elastKoeff;
 +
            if (count) arc.x = w - r;
 +
            dx = -Math.abs(w - arcR);
 +
        }
 +
        if (arcL + dx < 0) {
 +
            vx = Math.abs(vx)*elastKoeff;
 +
            if (count) arc.x = r;
 +
            dx = Math.abs(arcL);
 +
        }
  
        fx = - B * vx; fy = mg - B * vy;
+
        if (count) {arc.x += dx;     arc.y += dy;}
        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();  // функция, выполняющаяся на каждом шаге
 
 
}
 
}
</syntaxhighlight>
+
</source>
 
</toggledisplay>
 
</toggledisplay>
 
== См. также ==
 
*[[JavaScript-пружина]]
 
*[[JavaScript-mechanics-box2D]]
 
*[[JavaScript-приложения]]
 
 
[[Category: Виртуальная лаборатория]]
 
[[Category: Программирование]]
 
[[Category: JavaScript]]
 
Вам запрещено изменять защиту статьи. Edit Создать редактором

Обратите внимание, что все добавления и изменения текста статьи рассматриваются как выпущенные на условиях лицензии Public Domain (см. Department of Theoretical and Applied Mechanics:Авторские права). Если вы не хотите, чтобы ваши тексты свободно распространялись и редактировались любым желающим, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого.
НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ МАТЕРИАЛЫ, ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ!

To protect the wiki against automated edit spam, we kindly ask you to solve the following CAPTCHA:

Отменить | Справка по редактированию  (в новом окне)
Источник — «http://tm.spbstu.ru/JavaScript-mechanics»