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

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
Строка 12: Строка 12:
 
<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">  
 
Файл '''"mechanics.js"'''
 
Файл '''"mechanics.js"'''
 
<source lang="javascript" first-line="1">
 
<source lang="javascript" first-line="1">
 
function MainMech(canvas) {
 
function MainMech(canvas) {
 +
 +
    // Предварительные установки   
 +
 
     var context = canvas.getContext("2d");
 
     var context = canvas.getContext("2d");
    var w = canvas.width;
 
    var h = canvas.height;
 
  
     const g0 = 1;                     // масштаб ускорения
+
     const Pi = 3.1415926;          // число "пи"   
     const r0 = h;                     // масштаб длины - высота окна
+
 
     const t0 = Math.sqrt(2*r0/g0);    // масштаб времени - за сколько времени шар пролетит весь экран по вертикали
+
    const m0 = 1;                   // масштаб массы
     const v0 = g0*t0;                 // масштаб скорости - скорость в нижней точке экрана
+
     const T0 = 1;                   // масштаб времени (период колебаний исходной системы)
 +
     const a0 = 1;                  // масштаб расстояния (диаметр шара)
 +
 
 +
    const g0 = 2 * a0 / T0 / T0;    // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
 +
 
 +
    const k0 = 2 * Pi / T0;          // масштаб частоты
 +
    const C0 = m0 * k0 * k0;          // масштаб жесткости
 +
    const B0 = 2 * m0 * k0;        // масштаб вязкости
 +
 
 +
    // *** Задание физических параметров ***
 +
 
 +
    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;              // радиус шара
  
     const r = r0  / 40;               // радиус шара
+
     var x = 4 * r; var y = h - r; // начальное положение шара
    const g = g0;                    // 9.8 px, а не метров
 
    const dt = t0* 0.08;              // шаг интегрирования
 
  
     var count = true;                 // проводить ли расчет системы
+
     var count = true;                 // проводить ли расчет системы
  
 
     // создаем объект, связанный с элементом canvas на html странице
 
     // создаем объект, связанный с элементом canvas на html странице
 
     var ocanvas = oCanvas.create({
 
     var ocanvas = oCanvas.create({
         canvas: "#canvasMech",       // canvasMech - id объекта canvas на html странице
+
         canvas: "#canvasMech",       // canvasMech - id объекта canvas на html странице
         fps: 60                      // сколько кадров в секунду
+
         fps: fps                        // сколько кадров в секунду
 
     });
 
     });
  
 
     // создаем шар
 
     // создаем шар
 
     var arc = ocanvas.display.arc({
 
     var arc = ocanvas.display.arc({
         x: 4*r,
+
         x: x * scale,
         y: r0/2,
+
         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 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;           // на время захвата - отключить расчет
+
             count = false;           // на время захвата - отключить расчет
             this.fill = "rgba(0, 0, 255, 0.5)";     // пока держим шарик - он полупрозрачен
+
             this.fill = "rgba(0, 0, 255, 0.5)";     // пока держим шарик - он полупрозрачен
            m0x = 0;    m0y = 0;
+
        mx = ocanvas.mouse.x;   my = ocanvas.mouse.y;
            mx = 0;     my = 0;
 
 
         },
 
         },
 
         move: function ()  {
 
         move: function ()  {
            m0x = mx;   m0y = my;
+
x = arc.x / scale;    y = arc.y / scale;
            mx = ocanvas.mouse.x;
+
        vx = .001*(ocanvas.mouse.x-mx)/dt/fps;   vy = .001*(ocanvas.mouse.y-my)/dt/fps;
            my = ocanvas.mouse.y;
+
        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)";      // отпускаем шарик - полупрозрачность убирается
            // толкаем шарик по направлению движения мыши
+
      }
            vx = (mx-m0x)*2/dt;
 
            vy = (my-m0y)*2/dt;
 
        }
 
 
     });
 
     });
 +
   
 
     ocanvas.bind("mousedown", function () {count = false;});    // заморозить фигуру при клике на поле
 
     ocanvas.bind("mousedown", function () {count = false;});    // заморозить фигуру при клике на поле
  
     var wx = 0;            var wy = g;             // ускорение
+
     var fx = 0;            var fy = mg;             // сила, действующая на шар
     var vx = 0;             var vy = 0;             // скорость
+
     var vx = 0;           var vy = 0;             // скорость
 +
 
 
     function physics(){                            // то, что происходит каждый шаг времени
 
     function physics(){                            // то, что происходит каждый шаг времени
        if (!count) return;
 
 
        vx += wx*dt;      vy += wy*dt;
 
        var dx = vx*dt;    var dy = vy*dt;
 
        arc.x += dx;        arc.y += dy;
 
  
        // проверка граничных условий
+
if (!count) return;
        if (arc.y + r > r0) {          // нижняя граница (ось "y" направлена вниз)
+
    for (var s=1; s<=spf; s++) {
            arc.y = r0-r;
 
            vy = -vy;
 
        }
 
        if (arc.y - r < 0) {           // верхняя граница
 
            arc.y = r;
 
            vy = -vy;
 
        }
 
  
        if (arc.x + r > w) {           // правая граница
+
        fx = - B * vx; fy = mg - B * vy;
            arc.x = w-r;
+
        if (y + r > h) { fy += -C * (y + r - h) - B1 * vy; }
            vx = -vx;
+
        if (y - r < 0) { fy += -C * (y - r) - B1 * vy;}
        }
+
        if (x + r > w) { fx += -C * (x + r - w) - B1 * vx; }
        if (arc.x - r + dx < 0) {       // левая граница
+
        if (x - r < 0) { fx += -C * (x - r) - B1 * vx; }
            arc.x = r;
+
            vx = -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();  // функция, выполняющаяся на каждом шаге
 
}
 
}

Версия 04:24, 12 марта 2014

Кафедра ТМ > Программирование > Интернет > JavaScript > Механика

Если у вас отображается старая версия программы - нажмите "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");

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

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

    const g0 = 2 * a0 / T0 / T0;    // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)

    const k0 = 2 * Pi / T0;           	// масштаб частоты
    const C0 = m0 * k0 * k0;          	// масштаб жесткости
    const B0 = 2 * m0 * k0;  	      	// масштаб вязкости

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

    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 странице
    var ocanvas = oCanvas.create({
        canvas: "#canvasMech",        	// canvasMech - id объекта canvas на html странице
        fps: fps                        // сколько кадров в секунду
    });

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

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

    var fx = 0;            var fy = mg;             // сила, действующая на шар
    var vx = 0;            var vy = 0;              // скорость

    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();   // функция, выполняющаяся на каждом шаге
}

</toggledisplay>

См. также