JavaScript-mechanics — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
Строка 1: Строка 1:
Если у вас отображается старая версия программы - нажмите '''Ctrl + F5'''
+
Если у вас отображается старая версия программы - нажмите "'''Ctrl + F5'''"
 
<addscript src=ocanvas-251/>
 
<addscript src=ocanvas-251/>
 
<addscript src=Vector2D/>
 
<addscript src=Vector2D/>
 
<addscript src=mechanics/>
 
<addscript src=mechanics/>
 
<htmlet nocache="yes">mechanics_TM</htmlet>
 
<htmlet nocache="yes">mechanics_TM</htmlet>
 
  
 
Текст программы на языке JavaScript (разработчик [[Цветков Денис]], использована библиотека [http://ocanvas.org/ oCanvas]): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default">  
 
Текст программы на языке JavaScript (разработчик [[Цветков Денис]], использована библиотека [http://ocanvas.org/ oCanvas]): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default">  
Строка 11: Строка 10:
 
function MainMech(canvas) {
 
function MainMech(canvas) {
 
     var context = canvas.getContext("2d");
 
     var context = canvas.getContext("2d");
 
 
     var w = canvas.width;
 
     var w = canvas.width;
 
     var h = canvas.height;
 
     var h = canvas.height;
  
     var r = w  / 50;
+
     const g0 = 1;                     // масштаб ускорения
 
+
     const r0 = h;                     // масштаб длины - высота окна
    var ocanvas = oCanvas.create({
+
     const t0 = Math.sqrt(2*r0/g0);   // масштаб времени - за сколько времени шар пролетит весь экран по вертикали
        canvas: "#canvasMech",
+
    const v0 = g0*t0;                 // масштаб скорости - скорость в нижней точке экрана
        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;
 
        }
 
    });
 
 
 
    ocanvas.setLoop(physics).start();
 
 
 
    // границы:
 
    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 a = new Vector2D(0, 0);
 
    var v = new Vector2D(0, 0);
 
 
 
 
 
    function physics(){ // то, что происходит каждый шаг времени
 
        const arcD = arc.y + r;
 
        const arcU = arc.y - r;
 
        const arcL = arc.x - r;
 
        const arcR = arc.x + r;
 
 
 
        var dr = new Vector2D(0, 0);
 
 
 
        a.set(0, g);
 
        v = v.add(a.multiple(dt));
 
        dr.set(v.multiple(dt));
 
 
 
 
 
        // проверка граничных условий
 
        if (arcD + dr.y > h) {
 
            v.y = -Math.abs(v.y)*elastKoeff;
 
            if (count) arc.y = h - r;
 
            dr.y = -Math.abs(h - arcD);
 
        }
 
        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);
 
        }
 
  
        if (count) {arc.x += dr.x;     arc.y += dr.y;}
+
     const r = r0  / 40;               // радиус шара
    }
+
     const g = g0*20000;              // 9.8 px, а не метров
}
+
     const dt = 1/(t0*2);             // шаг интегрирования
</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 count = true;                // проводить ли расчет системы
  
Старая версия (без векторов): <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default">
+
     // создаем объект, связанный с элементом canvas на html странице
Файл '''"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({
 
     var ocanvas = oCanvas.create({
         canvas: "#canvasMech",
+
         canvas: "#canvasMech",       // canvasMech - id объекта canvas на html странице
         fps: 60
+
         fps: t0*2                    // сколько кадров в секунду
 
     });
 
     });
  
 +
    // создаем шар
 
     var arc = ocanvas.display.arc({
 
     var arc = ocanvas.display.arc({
 
         x: 4*r,
 
         x: 4*r,
         y: h,
+
         y: r0/2,
 
         radius: r,
 
         radius: r,
 
         start: 0,
 
         start: 0,
 
         end: 360,
 
         end: 360,
         fill: "rgba(0, 0, 255, 1)"
+
         fill: "rgba(0, 0, 255, 1)"   // цвет
 
     }).add();
 
     }).add();
  
     var m0x = 0; var m0y = 0;
+
    // захват шара мышью
     var mx = 0; var my = 0;
+
     var m0x = 0;   var m0y = 0;     // предыдущая позиция мыши
 +
     var mx = 0;     var my = 0;       // актуальная позиция мыши
 
     arc.dragAndDrop({
 
     arc.dragAndDrop({
         changeZindex: true,
+
         changeZindex: true,           // если много шариков - захваченный будет нарисован спереди
 
         start: function ()  {
 
         start: function ()  {
             this.fill = "rgba(0, 0, 255, 0.5)";
+
            count = false;            // на время захвата - отключить расчет
            count = false;
+
             this.fill = "rgba(0, 0, 255, 0.5)";     // пока держим шарик - он полупрозрачен
             m0x = 0; m0y = 0;
+
             m0x = 0;   m0y = 0;
             mx = 0; my = 0;
+
             mx = 0;     my = 0;
 
         },
 
         },
 
         move: function ()  {
 
         move: function ()  {
             m0x = mx; m0y = my;
+
             m0x = mx;   m0y = my;
 
             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;
             vx = (mx-m0x)*100; vy = (my-m0y)*100;
+
            this.fill = "rgba(0, 0, 255, 1)";      // отпускаем шарик - полупрозрачность убирается
 +
            // толкаем шарик по направлению движения мыши
 +
             vx = (mx-m0x)*100;
 +
            vy = (my-m0y)*100;
 
         }
 
         }
 
     });
 
     });
 +
    ocanvas.bind("mousedown", function () {count = false;});    // заморозить фигуру при клике на поле
  
     ocanvas.setLoop(physics).start();
+
     var vvx = 0;            var vvy = g;            // ускорение
 +
    var vx = 0;            var vy = 0;            // скорость
 +
    function physics(){                            // то, что происходит каждый шаг времени
 +
        if (!count) return;
  
    // границы:
+
        vx += vvx*dt;       vy += vvy*dt;
    const xb0 = 0;
+
        var dx = vx*dt;    var dy = vy*dt;
    const xb1 = w;
+
         arc.x += dx;       arc.y += dy;
    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;
 
 
 
        ax = 0;            ay = g;
 
        vx += ax*dt;        vy += ay*dt;
 
        dx = vx*dt;        dy = vy*dt;
 
  
 
         // проверка граничных условий
 
         // проверка граничных условий
         if (arcD + dy > h) {
+
         if (arc.y + r > r0) {           // нижняя граница (ось "y" направлена вниз)
            vy = -Math.abs(vy)*elastKoeff;
+
             arc.y = r0-r;
             if (count) arc.y = h - r;
+
             vy = -vy;
             dy = -Math.abs(h - arcD);
 
 
         }
 
         }
         if (arcU + dy < 0) {
+
         if (arc.y - r < 0) {           // верхняя граница
             vy = Math.abs(vy)*elastKoeff;
+
             arc.y = r;
            if (count) arc.y = r;
+
             vy = -vy;
             dy = Math.abs(arcU);
 
 
         }
 
         }
         if (arcR + dx > w) {
+
 
             vx = -Math.abs(vx)*elastKoeff;
+
         if (arc.x + r > w) {           // правая граница
            if (count) arc.x = w - r;
+
             arc.x = w-r;
             dx = -Math.abs(w - arcR);
+
             vx = -vx;
 
         }
 
         }
         if (arcL + dx < 0) {
+
         if (arc.x - r + dx < 0) {       // левая граница
             vx = Math.abs(vx)*elastKoeff;
+
             arc.x = r;
            if (count) arc.x = r;
+
             vx = -vx;
             dx = Math.abs(arcL);
 
 
         }
 
         }
 
        if (count) {arc.x += dx;    arc.y += dy;}
 
 
     }
 
     }
 +
    ocanvas.setLoop(physics).start();  // функция, выполняющаяся на каждом шаге
 
}
 
}
 
</source>
 
</source>

Версия 21:40, 24 февраля 2014

Если у вас отображается старая версия программы - нажмите "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");
    var w = canvas.width;
    var h = canvas.height;

    const g0 = 1;                     // масштаб ускорения
    const r0 = h;                     // масштаб длины - высота окна
    const t0 = Math.sqrt(2*r0/g0);    // масштаб времени - за сколько времени шар пролетит весь экран по вертикали
    const v0 = g0*t0;                 // масштаб скорости - скорость в нижней точке экрана

    const r = r0  / 40;               // радиус шара
    const g = g0*20000;               // 9.8 px, а не метров
    const dt = 1/(t0*2);              // шаг интегрирования

    var count = true;                 // проводить ли расчет системы

    // создаем объект, связанный с элементом canvas на html странице
    var ocanvas = oCanvas.create({
        canvas: "#canvasMech",        // canvasMech - id объекта canvas на html странице
        fps: t0*2                     // сколько кадров в секунду
    });

    // создаем шар
    var arc = ocanvas.display.arc({
        x: 4*r,
        y: r0/2,
        radius: r,
        start: 0,
        end: 360,
        fill: "rgba(0, 0, 255, 1)"    // цвет
    }).add();

    // захват шара мышью
    var m0x = 0;    var m0y = 0;      // предыдущая позиция мыши
    var mx = 0;     var my = 0;       // актуальная позиция мыши
    arc.dragAndDrop({
        changeZindex: true,           // если много шариков - захваченный будет нарисован спереди
        start: function ()  {
            count = false;            // на время захвата - отключить расчет
            this.fill = "rgba(0, 0, 255, 0.5)";     // пока держим шарик - он полупрозрачен
            m0x = 0;    m0y = 0;
            mx = 0;     my = 0;
        },
        move: function ()  {
            m0x = mx;   m0y = my;
            mx = ocanvas.mouse.x;
            my = ocanvas.mouse.y;
        },
        end: function ()    {
            count = true;
            this.fill = "rgba(0, 0, 255, 1)";       // отпускаем шарик - полупрозрачность убирается
            // толкаем шарик по направлению движения мыши
            vx = (mx-m0x)*100;
            vy = (my-m0y)*100;
        }
    });
    ocanvas.bind("mousedown", function () {count = false;});    // заморозить фигуру при клике на поле

    var vvx = 0;            var vvy = g;            // ускорение
    var vx = 0;             var vy = 0;             // скорость
    function physics(){                             // то, что происходит каждый шаг времени
        if (!count) return;

        vx += vvx*dt;       vy += vvy*dt;
        var dx = vx*dt;     var dy = vy*dt;
        arc.x += dx;        arc.y += dy;

        // проверка граничных условий
        if (arc.y + r > r0) {            // нижняя граница (ось "y" направлена вниз)
            arc.y = r0-r;
            vy = -vy;
        }
        if (arc.y - r < 0) {            // верхняя граница
            arc.y = r;
            vy = -vy;
        }

        if (arc.x + r > w) {            // правая граница
            arc.x = w-r;
            vx = -vx;
        }
        if (arc.x - r + dx < 0) {       // левая граница
            arc.x = r;
            vx = -vx;
        }
    }
    ocanvas.setLoop(physics).start();   // функция, выполняющаяся на каждом шаге
}

</toggledisplay>

См. также