Цепочка частиц с V-model взаимодействием — различия между версиями
Руслан (обсуждение | вклад) (→Реализации цепочки) |
|||
(не показаны 22 промежуточные версии 4 участников) | |||
Строка 1: | Строка 1: | ||
+ | [[en:Particles chain with V-model interaction]] | ||
+ | [[Виртуальная лаборатория]] > [[Цепочка частиц с V-model взаимодействием]] <HR> | ||
+ | |||
== Краткое описание V - model == | == Краткое описание V - model == | ||
Строка 22: | Строка 25: | ||
== Описание реализации цепочки == | == Описание реализации цепочки == | ||
+ | |||
+ | [[Файл: Fig3_bond_def.png|600px|thumb|right|Виды деформаций]] | ||
В программе реализованы три различных граничных условия, которые могут выбраны пользователем: | В программе реализованы три различных граничных условия, которые могут выбраны пользователем: | ||
Строка 39: | Строка 44: | ||
* Задавать относительное смещение частиц вдоль оси OX | * Задавать относительное смещение частиц вдоль оси OX | ||
− | * Задавать относительное смещение частиц вдоль оси OY | + | * Задавать относительное смещение частиц вдоль оси OY |
Так же есть возможность задавать коэффициенты жесткости системы на различные движения. Которые связаны с коэффициентами из указанных выше формул для V - model. | Так же есть возможность задавать коэффициенты жесткости системы на различные движения. Которые связаны с коэффициентами из указанных выше формул для V - model. | ||
− | |||
− | |||
* Жесткость на растяжение-сжатие: <math>c_a = B_1 </math> | * Жесткость на растяжение-сжатие: <math>c_a = B_1 </math> | ||
Строка 57: | Строка 60: | ||
Приведенная ниже программа реализует цепочку частиц, взаимодействие между которыми является V - model. | Приведенная ниже программа реализует цепочку частиц, взаимодействие между которыми является V - model. | ||
− | {{#widget:Iframe |url=http://tm.spbstu.ru | + | {{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Lapin/v_model.html |width=1200 |height=550 |border=0 }} |
+ | |||
+ | Скачать [[Медиа:V-model.zip|V-model]]. | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed" style="width:100%" > | ||
+ | '''Текст программы на языке JavaScript (разработчик [[Лапин Руслан]]):''' | ||
+ | |||
+ | <div class="mw-collapsible-content"> | ||
+ | Файл '''"V-model.js"''' | ||
+ | <syntaxhighlight lang="javascript" line start="1" enclose="div"> | ||
+ | function MainParticle(canvas) { | ||
+ | // Предварительные установки | ||
+ | var context = canvas.getContext("2d"); // на context происходит рисование | ||
+ | |||
+ | // Задание констант | ||
+ | const Pi = 3.1415926; // число "пи" | ||
+ | const m0 = 1; // масштаб массы | ||
+ | const T0 = 1; // масштаб времени (период колебаний исходной системы) | ||
+ | const a0 = 1; // масштаб расстояния (диаметр шара) | ||
+ | const g0 = a0 / T0 / T0; // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0) | ||
+ | const k0 = 2 * Pi / T0; // масштаб частоты | ||
+ | //const C0 = m0 * k0 * k0; // масштаб жесткости | ||
+ | const C0 = 1; | ||
+ | const B0 = 2 * m0 * k0; // масштаб вязкости | ||
+ | |||
+ | // *** Задание физических параметров *** | ||
+ | |||
+ | const Ny = 5; // число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна) | ||
+ | const Nx = 5; | ||
+ | const m = 1 * m0; // масса | ||
+ | const Cwall = 10 * C0; // жесткость стен | ||
+ | //const B = 0.01 * B0; // вязкость среды | ||
+ | const B = 0; | ||
+ | const B1 = 0.03 * B0; // вязкость на стенках | ||
+ | //const B1 = 0; | ||
+ | //var mg = 0.25 * m * g0; // сила тяжести | ||
+ | const r = 0.5 * a0; // радиус частицы в расчетных координатах | ||
+ | var stiff = 1 * C0; // "жесткость" пружинки | ||
+ | |||
+ | var vx0 = 0 * a0/T0; | ||
+ | var vy0 = 0 * a0/T0; | ||
+ | //Text_vx0.value = vx0; | ||
+ | |||
+ | // *** Параметры системы *** | ||
+ | var c = 1;// жесткость | ||
+ | var n = 10;// количество частиц | ||
+ | var c_a = 100//1;//longitudinal | ||
+ | var c_d = 100//c_a*1;//shear | ||
+ | var c_b = 0.1//c_a;//bending | ||
+ | var c_t = 1;//torsional | ||
+ | var J = 1; | ||
+ | var m_0 = 1.5; | ||
+ | var f = 0 ;//вариант либо свободное тело, либо закрепелнный край | ||
+ | var ugol = 0; | ||
+ | var sm_x = 0; | ||
+ | var sm_y = 0; | ||
+ | |||
+ | |||
+ | // *** Задание вычислительных параметров *** | ||
+ | |||
+ | const fps = 50; // frames per second - число кадров в секунду (качеcтво отображения)50 | ||
+ | const spf = 10;//5; // steps per frame - число шагов интегрирования между кадрами (скорость расчета) | ||
+ | const dt = 1 * T0 / fps; // шаг интегрирования | ||
+ | |||
+ | // Задание констант для рисования | ||
+ | const scale =100* canvas.height / Ny / a0; // масштабный коэффициент для перехода от расчетных к экранным координатам | ||
+ | |||
+ | var w = canvas.width / scale; // ширина окна в расчетных координатах | ||
+ | var h = canvas.height / scale; // высота окна в расчетных координатах | ||
+ | var k1v; var k2v; var k3v; var k4v; var k1x; var k2x; var k3x; var k4x; | ||
+ | var T1;var T2; var T1_; var T2_; | ||
+ | var rectH = 50; | ||
+ | var rectW = 50; | ||
+ | var diag = (rectH/scale)*Math.cos(45*Math.PI/180); | ||
+ | var koeff = 1; | ||
+ | var B_1 =c_a; | ||
+ | var B_2 = c_d*diag*diag; | ||
+ | var B_4 = c_t; | ||
+ | var B_3 = c_b - B_2/4 - B_4/2; | ||
+ | |||
+ | // ------------------------------- Выполнение программы ------------------------------------------ | ||
+ | // Добавление шара | ||
+ | balls=[]//массив содержащий частицы | ||
+ | j=1; | ||
+ | for (i = 0;i<n/2;i++) | ||
+ | { | ||
+ | var b = []; | ||
+ | var b1 = []; | ||
+ | var time = 1; | ||
+ | b.fi_x = 0*j; //угол с осью ОХ | ||
+ | b.omega=0;//угловая скорость | ||
+ | var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования. | ||
+ | j=j*(-1); | ||
+ | b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0; // расчетные координаты шара | ||
+ | b.Fx=0;b.Fy=0; | ||
+ | b.x_ = b.x; b.y_ = b.y; | ||
+ | b.fx = 0; b.fy = 0; // сила, действующая на шар | ||
+ | b.vx = vx0; b.vy = vy0; // начальная скорость | ||
+ | b1.fi_x = 0*j; //угол с осью ОХ | ||
+ | b1.omega=0; | ||
+ | b1.Fx=0;b1.Fy=0; | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2 ; // расчетные координаты шара | ||
+ | b1.x_ = b.x; b1.y_ = b.y; | ||
+ | b1.fx = 0; b1.fy = 0; // сила, действующая на шар | ||
+ | b1.vx = vx0; b1.vy = vy0; // начальная скорость | ||
+ | balls[n/2-(i+1)]=b;//[2*i] | ||
+ | balls[n/2+(i)] = b1;//[2*i+1] | ||
+ | |||
+ | } | ||
+ | // Основной цикл программы | ||
+ | setInterval(control, 1500 / fps); // функция control вызывается с периодом, определяемым вторым параметром | ||
+ | |||
+ | // --------------------------------------------------------------------------------------------------------------------- | ||
+ | // --------------------------------- Определение всех функций ----------------------------------- | ||
+ | // --------------------------------------------------------------------------------------------------------------------- | ||
+ | |||
+ | // основная функция, вызываемая в программе | ||
+ | function control() | ||
+ | { | ||
+ | physics(); // делаем spf шагов интегрирование | ||
+ | draw(); // рисуем частицу | ||
+ | } | ||
+ | //=======================новое задание начального состояния | ||
+ | function rebild()//новое задание начального состояния | ||
+ | { | ||
+ | time = 1; | ||
+ | balls=[] | ||
+ | j=1; | ||
+ | ugol = 0; | ||
+ | sm_x = 0; | ||
+ | sm_y = 0; | ||
+ | for (i = 0;i<n/2;i++) | ||
+ | { | ||
+ | var b = []; | ||
+ | var b1 = []; | ||
+ | var time = 1; | ||
+ | b.fi_x = 0*j; //угол с осью ОХ | ||
+ | b.omega=0;//угловая скорость | ||
+ | var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования. | ||
+ | j=j*(-1); | ||
+ | b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0; // расчетные координаты шара | ||
+ | b.Fx=0;b.Fy=0; | ||
+ | b.x_ = b.x; b.y_ = b.y; | ||
+ | b.fx = 0; b.fy = 0; // сила, действующая на шар | ||
+ | b.vx = vx0; b.vy = vy0; // начальная скорость | ||
+ | b1.fi_x = 0*j; //угол с осью ОХ | ||
+ | b1.omega=0; | ||
+ | b1.Fx=0;b1.Fy=0; | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2 ; // расчетные координаты шара | ||
+ | b1.x_ = b.x; b1.y_ = b.y; | ||
+ | b1.fx = 0; b1.fy = 0; // сила, действующая на шар | ||
+ | b1.vx = vx0; b1.vy = vy0; // начальная скорость | ||
+ | balls[n/2-(i+1)]=b;//[2*i] | ||
+ | balls[n/2+(i)] = b1;//[2*i+1] | ||
+ | |||
+ | } | ||
+ | context.clearRect(0, 0, w * scale, h * scale); | ||
+ | } | ||
+ | //=======================Выбор типа задачи====================== | ||
+ | |||
+ | radio_pic_1.onchange = function() {f = 0;rebild();};//свободное тело | ||
+ | radio_pic_2.onchange = function() {f = 1;rebild();};//закрепленный край | ||
+ | radio_pic_3.onchange = function() {f = 2;rebild();};//закрепелнные края | ||
+ | |||
+ | // Реакция на изменение значения в чекбоксе | ||
+ | |||
+ | this.new_start = function() | ||
+ | { | ||
+ | rebild(); | ||
+ | } | ||
+ | this.set_c_a = function(input) | ||
+ | { | ||
+ | c_a = Number(input); | ||
+ | B_1 =c_a; | ||
+ | time = 1; | ||
+ | for (i = 0;i<n/2;i++) | ||
+ | { | ||
+ | var b = []; | ||
+ | var b1 = []; | ||
+ | var time = 1; | ||
+ | b.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b.omega=0;//угловая скорость | ||
+ | var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования. | ||
+ | j=j*(-1); | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара | ||
+ | b.Fx=0;b.Fy=0; | ||
+ | b.x_ = b.x; b.y_ = b.y; | ||
+ | b.fx = 0; b.fy = 0; // сила, действующая на шар | ||
+ | b.vx = vx0; b.vy = vy0; // начальная скорость | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.omega=0; | ||
+ | b1.Fx=0;b1.Fy=0; | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; // расчетные координаты шара | ||
+ | b1.x_ = b.x; b1.y_ = b.y; | ||
+ | b1.fx = 0; b1.fy = 0; // сила, действующая на шар | ||
+ | b1.vx = vx0; b1.vy = vy0; // начальная скорость | ||
+ | balls[n/2-(i+1)]=b;//[2*i] | ||
+ | balls[n/2+(i)] = b1;//[2*i+1] | ||
+ | |||
+ | } | ||
+ | context.clearRect(0, 0, w * scale, h * scale); | ||
+ | } | ||
+ | this.set_c_b = function(input) | ||
+ | { | ||
+ | c_b = Number(input); | ||
+ | B_3 = c_b - B_2/4 - B_4/2; | ||
+ | time = 1; | ||
+ | for (i = 0;i<n/2;i++) | ||
+ | { | ||
+ | var b = []; | ||
+ | var b1 = []; | ||
+ | var time = 1; | ||
+ | |||
+ | b.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b.omega=0;//угловая скорость | ||
+ | var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования. | ||
+ | j=j*(-1); | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара | ||
+ | b.Fx=0;b.Fy=0; | ||
+ | b.x_ = b.x; b.y_ = b.y; | ||
+ | b.fx = 0; b.fy = 0; // сила, действующая на шар | ||
+ | b.vx = vx0; b.vy = vy0; // начальная скорость | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.omega=0; | ||
+ | b1.Fx=0;b1.Fy=0; | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; // расчетные координаты шара | ||
+ | b1.x_ = b.x; b1.y_ = b.y; | ||
+ | b1.fx = 0; b1.fy = 0; // сила, действующая на шар | ||
+ | b1.vx = vx0; b1.vy = vy0; // начальная скорость | ||
+ | balls[n/2-(i+1)]=b;//[2*i] | ||
+ | balls[n/2+(i)] = b1;//[2*i+1] | ||
+ | |||
+ | } | ||
+ | } | ||
+ | this.set_c_d = function(input) | ||
+ | { | ||
+ | c_d = Number(input); | ||
+ | B_2 = c_d*diag*diag; | ||
+ | time = 1; | ||
+ | for (i = 0;i<n/2;i++) | ||
+ | { | ||
+ | var b = []; | ||
+ | var b1 = []; | ||
+ | var time = 1; | ||
+ | |||
+ | b.fi_x = 10*j; //угол с осью ОХ | ||
+ | b.omega=0;//угловая скорость | ||
+ | var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования. | ||
+ | j=j*(-1); | ||
+ | b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.00; // расчетные координаты шара | ||
+ | |||
+ | b.Fx=0;b.Fy=0; | ||
+ | b.x_ = b.x; b.y_ = b.y; | ||
+ | b.fx = 0; b.fy = 0; // сила, действующая на шар | ||
+ | b.vx = vx0; b.vy = vy0; // начальная скорость | ||
+ | b1.fi_x = 10*j; //угол с осью ОХ | ||
+ | b1.omega=0; | ||
+ | b1.Fx=0;b1.Fy=0; | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2 ; // расчетные координаты шара | ||
+ | b1.x_ = b.x; b1.y_ = b.y; | ||
+ | b1.fx = 0; b1.fy = 0; // сила, действующая на шар | ||
+ | b1.vx = vx0; b1.vy = vy0; // начальная скорость | ||
+ | balls[n/2-(i+1)]=b;//[2*i] | ||
+ | balls[n/2+(i)] = b1;//[2*i+1] | ||
+ | } | ||
+ | context.clearRect(0, 0, w * scale, h * scale); | ||
+ | } | ||
+ | this.set_c_t = function(input) | ||
+ | { | ||
+ | c_t = Number(input); | ||
+ | B_4 = c_t; | ||
+ | time = 1; | ||
+ | for (i = 0;i<n/2;i++) | ||
+ | { | ||
+ | var b = []; | ||
+ | var b1 = []; | ||
+ | var time = 1; | ||
+ | |||
+ | b.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b.omega=0;//угловая скорость | ||
+ | var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования. | ||
+ | j=j*(-1); | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара | ||
+ | |||
+ | b.Fx=0;b.Fy=0; | ||
+ | b.x_ = b.x; b.y_ = b.y; | ||
+ | b.fx = 0; b.fy = 0; // сила, действующая на шар | ||
+ | b.vx = vx0; b.vy = vy0; // начальная скорость | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.omega=0; | ||
+ | b1.Fx=0;b1.Fy=0; | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; // расчетные координаты шара | ||
+ | b1.x_ = b.x; b1.y_ = b.y; | ||
+ | b1.fx = 0; b1.fy = 0; // сила, действующая на шар | ||
+ | b1.vx = vx0; b1.vy = vy0; // начальная скорость | ||
+ | balls[n/2-(i+1)]=b;//[2*i] | ||
+ | balls[n/2+(i)] = b1;//[2*i+1] | ||
+ | } | ||
+ | context.clearRect(0, 0, w * scale, h * scale); | ||
+ | } | ||
+ | |||
+ | slider_input.oninput = function() { | ||
+ | ugol = slider_input.value; | ||
+ | time = 1; | ||
+ | for (i = 0;i<n/2;i++) | ||
+ | { | ||
+ | var b = []; | ||
+ | var b1 = []; | ||
+ | var time = 1; | ||
+ | switch (f) | ||
+ | { | ||
+ | case 0: | ||
+ | b.fi_x = ugol*j; | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); | ||
+ | j=j*(-1); | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | break; | ||
+ | case 1: | ||
+ | if (i ==((n/2)-1))//закрепление края | ||
+ | { | ||
+ | b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0; | ||
+ | b.fi_x = 0; | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | b.fi_x = ugol*j; | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара | ||
+ | j=j*(-1); | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | } | ||
+ | break; | ||
+ | case 2: | ||
+ | if (i ==((n/2)-1))//закрепление краев | ||
+ | { | ||
+ | b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0; | ||
+ | b.fi_x = 0; | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2.0; | ||
+ | b1.fi_x = 0; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | b.fi_x = ugol*j; | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара | ||
+ | j=j*(-1); | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | } | ||
+ | break; | ||
+ | } | ||
+ | var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования. | ||
+ | b.omega=0; | ||
+ | b.Fx=0;b.Fy=0; | ||
+ | b.x_ = b.x; b.y_ = b.y; | ||
+ | b.fx = 0; b.fy = 0; // сила, действующая на шар | ||
+ | b.vx = vx0; b.vy = vy0; // начальная скорость | ||
+ | b1.omega=0; | ||
+ | b1.Fx=0;b1.Fy=0; | ||
+ | b1.x_ = b.x; b1.y_ = b.y; | ||
+ | b1.fx = 0; b1.fy = 0; // сила, действующая на шар | ||
+ | b1.vx = vx0; b1.vy = vy0; // начальная скорость | ||
+ | balls[n/2-(i+1)]=b;//[2*i] | ||
+ | balls[n/2+(i)] = b1;//[2*i+1] | ||
+ | |||
+ | } | ||
+ | context.clearRect(0, 0, w * scale, h * scale); | ||
+ | }; | ||
+ | |||
+ | slider_input_ox.oninput = function() { | ||
+ | sm_x = slider_input_ox.value; | ||
+ | time = 1; | ||
+ | j=1; | ||
+ | for (i = 0;i<n/2;i++) | ||
+ | { | ||
+ | var b = []; | ||
+ | var b1 = []; | ||
+ | var time = 1; | ||
+ | switch (f) | ||
+ | { | ||
+ | case 0: | ||
+ | b.fi_x = ugol*j; | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); | ||
+ | j=j*(-1); | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | break; | ||
+ | case 1: | ||
+ | if (i ==((n/2)-1))//закрепление края | ||
+ | { | ||
+ | b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0; | ||
+ | b.fi_x = 0; | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | b.fi_x = ugol*j; | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара | ||
+ | j=j*(-1); | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | } | ||
+ | break; | ||
+ | case 2: | ||
+ | if (i ==((n/2)-1))//закрепление краев | ||
+ | { | ||
+ | b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0; | ||
+ | b.fi_x = 0; | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2.0; | ||
+ | b1.fi_x = 0; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | b.fi_x = ugol*j; | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара | ||
+ | j=j*(-1); | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | } | ||
+ | break; | ||
+ | } | ||
+ | b.omega=0;//угловая скорость | ||
+ | var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования. | ||
+ | b.Fx=0;b.Fy=0; | ||
+ | b.x_ = b.x; b.y_ = b.y; | ||
+ | b.fx = 0; b.fy = 0; // сила, действующая на шар | ||
+ | b.vx = vx0; b.vy = vy0; // начальная скорость | ||
+ | b1.omega=0; | ||
+ | b1.Fx=0;b1.Fy=0; | ||
+ | b1.x_ = b.x; b1.y_ = b.y; | ||
+ | b1.fx = 0; b1.fy = 0; // сила, действующая на шар | ||
+ | b1.vx = vx0; b1.vy = vy0; // начальная скорость | ||
+ | balls[n/2-(i+1)]=b;//[2*i] | ||
+ | balls[n/2+(i)] = b1;//[2*i+1] | ||
+ | } | ||
+ | context.clearRect(0, 0, w * scale, h * scale); | ||
+ | }; | ||
+ | |||
+ | slider_input_oy.oninput = function() { | ||
+ | sm_y = slider_input_oy.value; | ||
+ | time = 1; | ||
+ | j=1; | ||
+ | for (i = 0;i<n/2;i++) | ||
+ | { | ||
+ | var b = []; | ||
+ | var b1 = []; | ||
+ | var time = 1; | ||
+ | switch (f) | ||
+ | { | ||
+ | case 0: | ||
+ | b.fi_x = ugol*j; | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); | ||
+ | j=j*(-1); | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | break; | ||
+ | case 1: | ||
+ | if (i ==((n/2)-1))//закрепление края | ||
+ | { | ||
+ | b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0; | ||
+ | b.fi_x = 0; | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | b.fi_x = ugol*j; | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара | ||
+ | j=j*(-1); | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | } | ||
+ | break; | ||
+ | case 2: | ||
+ | if (i ==((n/2)-1))//закрепление краев | ||
+ | { | ||
+ | b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0; | ||
+ | b.fi_x = 0; | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2.0; | ||
+ | b1.fi_x = 0; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | b.fi_x = ugol*j; | ||
+ | b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара | ||
+ | j=j*(-1); | ||
+ | b1.fi_x = ugol*j; //угол с осью ОХ | ||
+ | b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; | ||
+ | } | ||
+ | break; | ||
+ | } | ||
+ | b.omega=0;//угловая скорость | ||
+ | var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования. | ||
+ | b.Fx=0;b.Fy=0; | ||
+ | b.x_ = b.x; b.y_ = b.y; | ||
+ | b.fx = 0; b.fy = 0; // сила, действующая на шар | ||
+ | b.vx = vx0; b.vy = vy0; // начальная скорость | ||
+ | b1.omega=0; | ||
+ | b1.Fx=0;b1.Fy=0; | ||
+ | b1.x_ = b.x; b1.y_ = b.y; | ||
+ | b1.fx = 0; b1.fy = 0; // сила, действующая на шар | ||
+ | b1.vx = vx0; b1.vy = vy0; // начальная скорость | ||
+ | balls[n/2-(i+1)]=b;//[2*i] | ||
+ | balls[n/2+(i)] = b1;//[2*i+1] | ||
+ | |||
+ | } | ||
+ | context.clearRect(0, 0, w * scale, h * scale); | ||
+ | }; | ||
+ | // Функция, делающая spf шагов интегрирования | ||
+ | function physics() | ||
+ | { // то, что происходит каждый шаг времени | ||
+ | for (var s = 1; s <= spf; s++) //шаги интегрирования | ||
+ | { | ||
+ | |||
+ | for (i = 0;i<(n-1);i++) | ||
+ | { | ||
+ | |||
+ | d =[]; | ||
+ | R = 1; | ||
+ | b = balls[i];//balls[2*i]; | ||
+ | b1 = balls[i+1];//balls[2*i+1]; | ||
+ | D = Math.sqrt((b.x-b1.x)*(b.x-b1.x)+(b.y-b1.y)*(b.y-b1.y));//Math.abs((b.x-b1.x));//Math.sqrt((b.x-b1.x)*(b.x-b1.x)+(b.y-b1.y)*(b.y-b1.y))-2*diag; | ||
+ | d.fi_x = 180*Math.asin((b1.y-b.y)/D)/3.14; | ||
+ | pr = 3.14/180; | ||
+ | fi = 180+b1.fi_x | ||
+ | |||
+ | //=============================================Силы===================================== | ||
+ | A = -Math.cos(inRad(fi))*Math.cos(inRad(d.fi_x))-Math.sin(inRad(fi))*Math.sin(inRad(d.fi_x))+Math.cos(inRad(b.fi_x))*Math.cos(inRad(d.fi_x))+Math.sin(inRad(b.fi_x))*Math.sin(inRad(d.fi_x)); | ||
+ | b.Fx = B_1*(D-2*diag)*Math.cos(inRad(d.fi_x))+(B_2/2/D)*( Math.cos(inRad(fi))-Math.cos(inRad(b.fi_x))+A*Math.cos(inRad(d.fi_x))); | ||
+ | b1.Fx = -b.Fx; | ||
+ | b.Fy = B_1*(D-2*diag)*Math.sin(inRad(d.fi_x))+(B_2/2/D)*( Math.sin(inRad(fi))-Math.sin(inRad(b.fi_x))+A*Math.sin(inRad(d.fi_x))); | ||
+ | b1.Fy = -b.Fy; | ||
+ | M_tb = B_3*(Math.cos(inRad(fi))*Math.sin(inRad(b.fi_x))-Math.cos(inRad(b.fi_x))*Math.sin(inRad(fi)))-(B_4/2)*(Math.cos(inRad(fi-90))*Math.sin(inRad(b.fi_x+90))-Math.sin(inRad(fi-90))*Math.cos(inRad(b.fi_x+90))); | ||
+ | b.fx = R * (b.Fy*Math.cos(inRad(b.fi_x))-b.Fx*Math.sin(inRad(b.fi_x))) - (B_2/2) * (Math.cos(inRad(d.fi_x))*Math.sin(inRad(b.fi_x))-Math.sin(inRad(d.fi_x))*Math.cos(inRad(b.fi_x))) + M_tb; | ||
+ | b1.fx = R * (-Math.cos(inRad(fi))*b.Fy+Math.sin(inRad(fi))*b.Fx) + (B_2/2) * (Math.cos(inRad(d.fi_x))*Math.sin(inRad(fi))-Math.sin(inRad(d.fi_x))*Math.cos(inRad(fi)))- M_tb; | ||
+ | |||
+ | //====================================================================================== | ||
+ | var J1 = 10000; | ||
+ | var m =1; | ||
+ | var beta_vr=0.00001//0.005; | ||
+ | var beta_x=0.5//1; | ||
+ | var beta_y=0.01//0.1; | ||
+ | //console.log(c_b); | ||
+ | if (f==0)//совбодное тело | ||
+ | { | ||
+ | x_v1=balls[i].vx; | ||
+ | y_v1=balls[i].vy; | ||
+ | x_v2=balls[i+1].vx; | ||
+ | y_v2=balls[i+1].vy; | ||
+ | vr1 = balls[i].omega; | ||
+ | vr2 = balls[i+1].omega; | ||
+ | balls[i] = b; | ||
+ | balls[i+1] = b1; | ||
+ | balls[i].omega+=J1*(balls[i].fx-beta_vr*vr1)*dt; | ||
+ | balls[i].vx+=m*(balls[i].Fx-beta_x*x_v1)*dt; | ||
+ | balls[i].vy+=m*(balls[i].Fy-beta_y*y_v1)*dt; | ||
+ | balls[i+1].omega+=J1*(balls[i+1].fx-beta_vr*vr2)*dt; | ||
+ | balls[i+1].vx+=m*(balls[i+1].Fx-beta_x*x_v2)*dt; | ||
+ | balls[i+1].vy+=m*(balls[i+1].Fy-beta_y*y_v2)*dt; | ||
+ | balls[i].y+=balls[i].vy*dt; | ||
+ | balls[i].fi_x+=balls[i].omega*dt; | ||
+ | balls[i].x+=balls[i].vx*dt; | ||
+ | balls[i+1].x+=balls[i+1].vx*dt; | ||
+ | balls[i+1].fi_x+=balls[i+1].omega*dt; | ||
+ | balls[i+1].y+=balls[i+1].vy*dt; | ||
+ | asd=balls[0].fx+balls[1].fx; | ||
+ | } | ||
+ | else//закрепелнный край | ||
+ | { | ||
+ | if (f==1)////закрепелнный край | ||
+ | { | ||
+ | balls[i] = b; | ||
+ | balls[i+1] = b1; | ||
+ | x_v1=balls[i].vx; | ||
+ | y_v1=balls[i].vy; | ||
+ | x_v2=balls[i+1].vx; | ||
+ | y_v2=balls[i+1].vy; | ||
+ | vr1 = balls[i].omega; | ||
+ | vr2 = balls[i+1].omega; | ||
+ | balls[i].omega+=J1*(balls[i].fx-beta_vr*vr1)*dt; | ||
+ | balls[i].vx+=m*(balls[i].Fx-beta_x*x_v1)*dt; | ||
+ | balls[i].vy+=m*(balls[i].Fy-beta_y*y_v1)*dt; | ||
+ | balls[i+1].omega+=J1*(balls[i+1].fx-beta_vr*vr2)*dt; | ||
+ | balls[i+1].vx+=m*(balls[i+1].Fx-beta_x*x_v2)*dt; | ||
+ | balls[i+1].vy+=m*(balls[i+1].Fy-beta_y*y_v2)*dt; | ||
+ | if (i>0) | ||
+ | { | ||
+ | balls[i].fi_x+=balls[i].omega*dt; | ||
+ | balls[i+1].y+=balls[i+1].vy*dt; | ||
+ | balls[i].y+=balls[i].vy*dt; | ||
+ | balls[i].x+=balls[i].vx*dt; | ||
+ | balls[i+1].x+=balls[i+1].vx*dt; | ||
+ | balls[i+1].fi_x+=balls[i+1].omega*dt; | ||
+ | } | ||
+ | } | ||
+ | else //оба края закрепелены | ||
+ | { | ||
+ | |||
+ | x_v1=balls[i].vx; | ||
+ | y_v1=balls[i].vy; | ||
+ | x_v2=balls[i+1].vx; | ||
+ | y_v2=balls[i+1].vy; | ||
+ | vr1 = balls[i].omega; | ||
+ | vr2 = balls[i+1].omega; | ||
+ | balls[i] = b; | ||
+ | balls[i+1] = b1; | ||
+ | balls[i].omega+=J1*(balls[i].fx-beta_vr*vr1)*dt; | ||
+ | balls[i].vx+=m*(balls[i].Fx-10*beta_x*x_v1)*dt; | ||
+ | balls[i].vy+=m*(balls[i].Fy-10*beta_y*y_v1)*dt; | ||
+ | balls[i+1].omega+=J1*(balls[i+1].fx-beta_vr*vr2)*dt; | ||
+ | balls[i+1].vx+=m*(balls[i+1].Fx-10*beta_x*x_v2)*dt; | ||
+ | balls[i+1].vy+=m*(balls[i+1].Fy-10*beta_y*y_v2)*dt; | ||
+ | if ((i>0)&&(i<(n-2))) | ||
+ | { | ||
+ | balls[i].fi_x+=balls[i].omega*dt; | ||
+ | balls[i+1].y+=balls[i+1].vy*dt; | ||
+ | balls[i].y+=balls[i].vy*dt; | ||
+ | balls[i].x+=balls[i].vx*dt; | ||
+ | balls[i+1].x+=balls[i+1].vx*dt; | ||
+ | balls[i+1].fi_x+=balls[i+1].omega*dt; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | time = time + 1; | ||
+ | } | ||
+ | } | ||
+ | // определение функции, вычисляющей силу | ||
+ | |||
+ | // определение функции, рисующией частицу, стенки и пр | ||
+ | context.fillStyle = "#3070d0"; // цвет | ||
+ | //===================================Взаимодествие мышью======================== | ||
+ | // функция запускается при нажатии клавиши мыши | ||
+ | canvasBalls.onmousedown = function(e) { | ||
+ | var m = mouseCoords(e); // получаем координаты курсора мыши | ||
+ | switch (f) | ||
+ | { | ||
+ | case(0): | ||
+ | var x = balls[n-1].x - m.x/scale; // расстояние от центра шара до курсора по оси x | ||
+ | var y = balls[n-1].y - m.y/scale; // расстояние от центра шара до курсора по оси y | ||
+ | var rLen2 = x * x + y * y; // квадрат расстояния между курсором и центром шара | ||
+ | if (rLen2 <= diag*diag) { // если курсор нажал на шар | ||
+ | xShift = balls[n-1].x - m.x/scale; // сдвиг курсора относительно центра шара по x | ||
+ | yShift = balls[n-1].y - m.y/scale; // сдвиг курсора относительно центра шара по y | ||
+ | canvasBalls.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения | ||
+ | } | ||
+ | break; | ||
+ | case(1): | ||
+ | var x = balls[n-1].x - m.x/scale; // расстояние от центра шара до курсора по оси x | ||
+ | var y = balls[n-1].y - m.y/scale; // расстояние от центра шара до курсора по оси y | ||
+ | var rLen2 = x * x + y * y; // квадрат расстояния между курсором и центром шара | ||
+ | if (rLen2 <= diag*diag) { // если курсор нажал на шар | ||
+ | xShift = balls[n-1].x - m.x/scale; // сдвиг курсора относительно центра шара по x | ||
+ | yShift = balls[n-1].y - m.y/scale; // сдвиг курсора относительно центра шара по y | ||
+ | canvasBalls.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения | ||
+ | } | ||
+ | break; | ||
+ | case (2): | ||
+ | case(0): | ||
+ | var x = balls[n/2].x - m.x/scale; // расстояние от центра шара до курсора по оси x | ||
+ | var y = balls[n/2].y - m.y/scale; // расстояние от центра шара до курсора по оси y | ||
+ | var rLen2 = x * x + y * y; // квадрат расстояния между курсором и центром шара | ||
+ | if (rLen2 <= diag*diag) { // если курсор нажал на шар | ||
+ | xShift = balls[n/2].x - m.x/scale; // сдвиг курсора относительно центра шара по x | ||
+ | yShift = balls[n/2].y - m.y/scale; // сдвиг курсора относительно центра шара по y | ||
+ | canvasBalls.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения | ||
+ | } | ||
+ | break; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | // функция запускается при отпускании клавиши мыши | ||
+ | document.onmouseup = function() { | ||
+ | canvasBalls.onmousemove = null; // когда клавиша отпущена - функции перемещения нету | ||
+ | }; | ||
+ | |||
+ | // функция запускается при перемещении мыши (много раз, в каждый момент перемещения) | ||
+ | // в нашем случае работает только с зажатой клавишей мыши | ||
+ | function mouseMove(e) { | ||
+ | switch (f) | ||
+ | { | ||
+ | case(0): | ||
+ | var m = mouseCoords(e); // получаем координаты курсора мыши | ||
+ | balls[n-1].x = m.x/scale + xShift; | ||
+ | balls[n-1].y = m.y/scale+ yShift; | ||
+ | draw(); | ||
+ | break; | ||
+ | case(1): | ||
+ | var m = mouseCoords(e); | ||
+ | x_nach =(w / 2)+diag*(n/2+2)*1.0; | ||
+ | y_nach = h / 2.0; | ||
+ | r_nach = Math.sqrt(x_nach*x_nach+y_nach*y_nach); | ||
+ | r_m = Math.sqrt(((m.x/scale-2*diag)-x_nach)*((m.x/scale-2*diag)-x_nach)+((m.y/scale)-y_nach)*((m.y/scale)-y_nach)); | ||
+ | console.log(x_nach); | ||
+ | console.log(m.x/scale); | ||
+ | //console.log(r_nach); | ||
+ | if (Math.abs(r_m)<(3*diag)) // получаем координаты курсора мыши | ||
+ | {pr_x = m.x/scale + xShift*0.01 -balls[n-1].x; | ||
+ | pr_y = m.y/scale+yShift-balls[n-1].y; | ||
+ | balls[n-1].x = m.x/scale + xShift*0.0001; | ||
+ | balls[n-1].y = m.y/scale+ yShift; | ||
+ | } | ||
+ | draw(); | ||
+ | break; | ||
+ | case(2): | ||
+ | var m = mouseCoords(e); // получаем координаты курсора мыши | ||
+ | balls[n/2].x = m.x/scale + xShift; | ||
+ | balls[n/2].y = m.y/scale+ yShift; | ||
+ | draw(); | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // функция возвращает координаты курсора мыши | ||
+ | function mouseCoords(e) { | ||
+ | var m = []; | ||
+ | var rect = canvasBalls.getBoundingClientRect(); | ||
+ | m.x = e.clientX - rect.left; | ||
+ | m.y = e.clientY - rect.top; | ||
+ | //console.log(m.x/scale); | ||
+ | //console.log(balls[n-1].x); | ||
+ | return m; | ||
+ | } | ||
+ | |||
+ | function inRad(num) | ||
+ | { | ||
+ | return num * Math.PI / 180; | ||
+ | } | ||
+ | |||
+ | function draw() | ||
+ | { | ||
+ | context.clearRect(0, 0, w * scale, h * scale); // очистить экран | ||
+ | for (var i =0;i<n;i++) | ||
+ | { | ||
+ | b = balls[i]; | ||
+ | context.beginPath(); | ||
+ | context.translate(b.x*scale,b.y * scale);//перенос в центр | ||
+ | context.rotate(inRad(b.fi_x-45)); | ||
+ | context.fillRect(-rectW/2, -rectH/2, rectW, rectH); | ||
+ | context.rotate(-inRad(b.fi_x-45)); | ||
+ | context.translate(-b.x * scale, -b.y * scale);//перенос обратно | ||
+ | context.closePath(); | ||
+ | context.stroke(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Файл '''"v-model.html"''' | ||
+ | <syntaxhighlight lang="html5" line start="1" enclose="div"> | ||
+ | <!DOCTYPE html> | ||
+ | <html> | ||
+ | <head> | ||
+ | <title> Particle </title> | ||
+ | <script src="V_model.js"></script> | ||
+ | </head> | ||
+ | <body> | ||
+ | <!-- Добавление области для рисования частицы --> | ||
+ | <canvas id="canvasBalls" width="800" height="400" style="border:1px solid #000000;"></canvas> | ||
+ | |||
+ | <div> | ||
+ | c_a = | ||
+ | <input id="Text_vx0" value = "100" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput=" | ||
+ | if (!this.checkValidity()) return; | ||
+ | app.set_c_a(this.value); | ||
+ | <!-- document.getElementById('Slider_02').value = this.value; --> | ||
+ | "> | ||
+ | <!-- Добавление слайдера --> | ||
+ | <!-- <input type="range" id="Slider_02" style="width: 100px;" oninput="app.set_02(this.value); document.getElementById('Text_02').value = this.value;"> --> | ||
+ | </I></font> | ||
+ | c_b = | ||
+ | <input id="Text_vx0" value = "0.1" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput=" | ||
+ | if (!this.checkValidity()) return; | ||
+ | app.set_c_b(this.value); | ||
+ | <!-- document.getElementById('Slider_02').value = this.value; --> | ||
+ | "> | ||
+ | <!-- Добавление слайдера --> | ||
+ | <!-- <input type="range" id="Slider_02" style="width: 100px;" oninput="app.set_02(this.value); document.getElementById('Text_02').value = this.value;"> --> | ||
+ | </I></font> | ||
+ | c_d = | ||
+ | <input id="Text_vx0" value = "100" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput=" | ||
+ | if (!this.checkValidity()) return; | ||
+ | app.set_c_d(this.value); | ||
+ | <!-- document.getElementById('Slider_02').value = this.value; --> | ||
+ | "> | ||
+ | <!-- Добавление слайдера --> | ||
+ | <!-- <input type="range" id="Slider_02" style="width: 100px;" oninput="app.set_02(this.value); document.getElementById('Text_02').value = this.value;"> --> | ||
+ | </I></font> | ||
+ | c_t = | ||
+ | <input id="Text_vx0" value = "1" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput=" | ||
+ | if (!this.checkValidity()) return; | ||
+ | app.set_c_t(this.value); | ||
+ | <!-- document.getElementById('Slider_02').value = this.value; --> | ||
+ | "> | ||
+ | <!-- Добавление слайдера --> | ||
+ | <!-- <input type="range" id="Slider_02" style="width: 100px;" oninput="app.set_02(this.value); document.getElementById('Text_02').value = this.value;"> --> | ||
+ | </I></font> | ||
+ | <input type="button" name="" onclick=" | ||
+ | app.new_start();" value="restart"/></div> | ||
+ | <div><input type="radio" id="radio_pic_1" name="pic" checked /> Free body | ||
+ | <input type="radio" id="radio_pic_2" name="pic" /> Fixed edge | ||
+ | <input type="radio" id="radio_pic_3" name="pic" /> Fixed edges <br></div> | ||
+ | <div>Angle of torsion | ||
+ | 0 | ||
+ | <input type="range" id="slider_input" min=0 max=40 value=0 step=0.5 style="width: 200px;">40 | ||
+ | <div>Shear OX | ||
+ | 0 | ||
+ | <input type="range" id="slider_input_ox" min=0 max=10 value=0 step=0.5 style="width: 200px;">10</div> | ||
+ | <div>Shear OY | ||
+ | 0 | ||
+ | <input type="range" id="slider_input_oy" min=0 max=10 value=0 step=0.5 style="width: 200px;">10</div> | ||
+ | <script type="text/javascript"> app = new MainParticle(document.getElementById('canvasBalls')); | ||
+ | </script> | ||
+ | </body> | ||
+ | </html> | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | </div> | ||
+ | |||
+ | |||
+ | == Ссылки == | ||
+ | * [[V-model | Основная статья про V-model]] | ||
+ | * [[VirtLab| Виртуальная лаборатория]] |
Текущая версия на 19:05, 18 января 2017
Виртуальная лаборатория > Цепочка частиц с V-model взаимодействиемКраткое описание V - model[править]
V-model используется для описания сыпучих твердых тел, например горных пород, керамики, бетона, нанокомпозитов и агломератов.
Модель описывается следующими формулами:
Сила взаимодействия:
Моменты:
Где
, , и - различные коэффициенты, которые являются характеристиками системы.
Описание реализации цепочки[править]
В программе реализованы три различных граничных условия, которые могут выбраны пользователем:
- Свободная цепочка
- Цепочка с зажатым левым краем
- Цепочка с зажатыми краями
Так же пользователь в первых двух случаях может перемещать крайнюю правую частицу, а в третьем случае может двигать центральную правую частицу.
Предусмотрена возможность задавать начальные условия для всей цепочки:
- Задавать угол закручивания частиц друг относительно друга.
- Задавать относительное смещение частиц вдоль оси OX
- Задавать относительное смещение частиц вдоль оси OY
Так же есть возможность задавать коэффициенты жесткости системы на различные движения. Которые связаны с коэффициентами из указанных выше формул для V - model.
- Жесткость на растяжение-сжатие:
- Жесткость на сдвиг:
- Жесткость на изгиб:
- Жесткость на кручение:
Реализации цепочки[править]
Приведенная ниже программа реализует цепочку частиц, взаимодействие между которыми является V - model.
Скачать V-model.
Текст программы на языке JavaScript (разработчик Лапин Руслан):
Файл "V-model.js"
1 function MainParticle(canvas) {
2 // Предварительные установки
3 var context = canvas.getContext("2d"); // на context происходит рисование
4
5 // Задание констант
6 const Pi = 3.1415926; // число "пи"
7 const m0 = 1; // масштаб массы
8 const T0 = 1; // масштаб времени (период колебаний исходной системы)
9 const a0 = 1; // масштаб расстояния (диаметр шара)
10 const g0 = a0 / T0 / T0; // масштаб ускорения (ускорение, при котором за T0 будет пройдено расстояние a0)
11 const k0 = 2 * Pi / T0; // масштаб частоты
12 //const C0 = m0 * k0 * k0; // масштаб жесткости
13 const C0 = 1;
14 const B0 = 2 * m0 * k0; // масштаб вязкости
15
16 // *** Задание физических параметров ***
17
18 const Ny = 5; // число шаров, помещающихся по вертикали в окно (задает размер шара относительно размера окна)
19 const Nx = 5;
20 const m = 1 * m0; // масса
21 const Cwall = 10 * C0; // жесткость стен
22 //const B = 0.01 * B0; // вязкость среды
23 const B = 0;
24 const B1 = 0.03 * B0; // вязкость на стенках
25 //const B1 = 0;
26 //var mg = 0.25 * m * g0; // сила тяжести
27 const r = 0.5 * a0; // радиус частицы в расчетных координатах
28 var stiff = 1 * C0; // "жесткость" пружинки
29
30 var vx0 = 0 * a0/T0;
31 var vy0 = 0 * a0/T0;
32 //Text_vx0.value = vx0;
33
34 // *** Параметры системы ***
35 var c = 1;// жесткость
36 var n = 10;// количество частиц
37 var c_a = 100//1;//longitudinal
38 var c_d = 100//c_a*1;//shear
39 var c_b = 0.1//c_a;//bending
40 var c_t = 1;//torsional
41 var J = 1;
42 var m_0 = 1.5;
43 var f = 0 ;//вариант либо свободное тело, либо закрепелнный край
44 var ugol = 0;
45 var sm_x = 0;
46 var sm_y = 0;
47
48
49 // *** Задание вычислительных параметров ***
50
51 const fps = 50; // frames per second - число кадров в секунду (качеcтво отображения)50
52 const spf = 10;//5; // steps per frame - число шагов интегрирования между кадрами (скорость расчета)
53 const dt = 1 * T0 / fps; // шаг интегрирования
54
55 // Задание констант для рисования
56 const scale =100* canvas.height / Ny / a0; // масштабный коэффициент для перехода от расчетных к экранным координатам
57
58 var w = canvas.width / scale; // ширина окна в расчетных координатах
59 var h = canvas.height / scale; // высота окна в расчетных координатах
60 var k1v; var k2v; var k3v; var k4v; var k1x; var k2x; var k3x; var k4x;
61 var T1;var T2; var T1_; var T2_;
62 var rectH = 50;
63 var rectW = 50;
64 var diag = (rectH/scale)*Math.cos(45*Math.PI/180);
65 var koeff = 1;
66 var B_1 =c_a;
67 var B_2 = c_d*diag*diag;
68 var B_4 = c_t;
69 var B_3 = c_b - B_2/4 - B_4/2;
70
71 // ------------------------------- Выполнение программы ------------------------------------------
72 // Добавление шара
73 balls=[]//массив содержащий частицы
74 j=1;
75 for (i = 0;i<n/2;i++)
76 {
77 var b = [];
78 var b1 = [];
79 var time = 1;
80 b.fi_x = 0*j; //угол с осью ОХ
81 b.omega=0;//угловая скорость
82 var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования.
83 j=j*(-1);
84 b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0; // расчетные координаты шара
85 b.Fx=0;b.Fy=0;
86 b.x_ = b.x; b.y_ = b.y;
87 b.fx = 0; b.fy = 0; // сила, действующая на шар
88 b.vx = vx0; b.vy = vy0; // начальная скорость
89 b1.fi_x = 0*j; //угол с осью ОХ
90 b1.omega=0;
91 b1.Fx=0;b1.Fy=0;
92 b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2 ; // расчетные координаты шара
93 b1.x_ = b.x; b1.y_ = b.y;
94 b1.fx = 0; b1.fy = 0; // сила, действующая на шар
95 b1.vx = vx0; b1.vy = vy0; // начальная скорость
96 balls[n/2-(i+1)]=b;//[2*i]
97 balls[n/2+(i)] = b1;//[2*i+1]
98
99 }
100 // Основной цикл программы
101 setInterval(control, 1500 / fps); // функция control вызывается с периодом, определяемым вторым параметром
102
103 // ---------------------------------------------------------------------------------------------------------------------
104 // --------------------------------- Определение всех функций -----------------------------------
105 // ---------------------------------------------------------------------------------------------------------------------
106
107 // основная функция, вызываемая в программе
108 function control()
109 {
110 physics(); // делаем spf шагов интегрирование
111 draw(); // рисуем частицу
112 }
113 //=======================новое задание начального состояния
114 function rebild()//новое задание начального состояния
115 {
116 time = 1;
117 balls=[]
118 j=1;
119 ugol = 0;
120 sm_x = 0;
121 sm_y = 0;
122 for (i = 0;i<n/2;i++)
123 {
124 var b = [];
125 var b1 = [];
126 var time = 1;
127 b.fi_x = 0*j; //угол с осью ОХ
128 b.omega=0;//угловая скорость
129 var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования.
130 j=j*(-1);
131 b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0; // расчетные координаты шара
132 b.Fx=0;b.Fy=0;
133 b.x_ = b.x; b.y_ = b.y;
134 b.fx = 0; b.fy = 0; // сила, действующая на шар
135 b.vx = vx0; b.vy = vy0; // начальная скорость
136 b1.fi_x = 0*j; //угол с осью ОХ
137 b1.omega=0;
138 b1.Fx=0;b1.Fy=0;
139 b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2 ; // расчетные координаты шара
140 b1.x_ = b.x; b1.y_ = b.y;
141 b1.fx = 0; b1.fy = 0; // сила, действующая на шар
142 b1.vx = vx0; b1.vy = vy0; // начальная скорость
143 balls[n/2-(i+1)]=b;//[2*i]
144 balls[n/2+(i)] = b1;//[2*i+1]
145
146 }
147 context.clearRect(0, 0, w * scale, h * scale);
148 }
149 //=======================Выбор типа задачи======================
150
151 radio_pic_1.onchange = function() {f = 0;rebild();};//свободное тело
152 radio_pic_2.onchange = function() {f = 1;rebild();};//закрепленный край
153 radio_pic_3.onchange = function() {f = 2;rebild();};//закрепелнные края
154
155 // Реакция на изменение значения в чекбоксе
156
157 this.new_start = function()
158 {
159 rebild();
160 }
161 this.set_c_a = function(input)
162 {
163 c_a = Number(input);
164 B_1 =c_a;
165 time = 1;
166 for (i = 0;i<n/2;i++)
167 {
168 var b = [];
169 var b1 = [];
170 var time = 1;
171 b.fi_x = ugol*j; //угол с осью ОХ
172 b.omega=0;//угловая скорость
173 var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования.
174 j=j*(-1);
175 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара
176 b.Fx=0;b.Fy=0;
177 b.x_ = b.x; b.y_ = b.y;
178 b.fx = 0; b.fy = 0; // сила, действующая на шар
179 b.vx = vx0; b.vy = vy0; // начальная скорость
180 b1.fi_x = ugol*j; //угол с осью ОХ
181 b1.omega=0;
182 b1.Fx=0;b1.Fy=0;
183 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; // расчетные координаты шара
184 b1.x_ = b.x; b1.y_ = b.y;
185 b1.fx = 0; b1.fy = 0; // сила, действующая на шар
186 b1.vx = vx0; b1.vy = vy0; // начальная скорость
187 balls[n/2-(i+1)]=b;//[2*i]
188 balls[n/2+(i)] = b1;//[2*i+1]
189
190 }
191 context.clearRect(0, 0, w * scale, h * scale);
192 }
193 this.set_c_b = function(input)
194 {
195 c_b = Number(input);
196 B_3 = c_b - B_2/4 - B_4/2;
197 time = 1;
198 for (i = 0;i<n/2;i++)
199 {
200 var b = [];
201 var b1 = [];
202 var time = 1;
203
204 b.fi_x = ugol*j; //угол с осью ОХ
205 b.omega=0;//угловая скорость
206 var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования.
207 j=j*(-1);
208 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара
209 b.Fx=0;b.Fy=0;
210 b.x_ = b.x; b.y_ = b.y;
211 b.fx = 0; b.fy = 0; // сила, действующая на шар
212 b.vx = vx0; b.vy = vy0; // начальная скорость
213 b1.fi_x = ugol*j; //угол с осью ОХ
214 b1.omega=0;
215 b1.Fx=0;b1.Fy=0;
216 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; // расчетные координаты шара
217 b1.x_ = b.x; b1.y_ = b.y;
218 b1.fx = 0; b1.fy = 0; // сила, действующая на шар
219 b1.vx = vx0; b1.vy = vy0; // начальная скорость
220 balls[n/2-(i+1)]=b;//[2*i]
221 balls[n/2+(i)] = b1;//[2*i+1]
222
223 }
224 }
225 this.set_c_d = function(input)
226 {
227 c_d = Number(input);
228 B_2 = c_d*diag*diag;
229 time = 1;
230 for (i = 0;i<n/2;i++)
231 {
232 var b = [];
233 var b1 = [];
234 var time = 1;
235
236 b.fi_x = 10*j; //угол с осью ОХ
237 b.omega=0;//угловая скорость
238 var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования.
239 j=j*(-1);
240 b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.00; // расчетные координаты шара
241
242 b.Fx=0;b.Fy=0;
243 b.x_ = b.x; b.y_ = b.y;
244 b.fx = 0; b.fy = 0; // сила, действующая на шар
245 b.vx = vx0; b.vy = vy0; // начальная скорость
246 b1.fi_x = 10*j; //угол с осью ОХ
247 b1.omega=0;
248 b1.Fx=0;b1.Fy=0;
249 b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2 ; // расчетные координаты шара
250 b1.x_ = b.x; b1.y_ = b.y;
251 b1.fx = 0; b1.fy = 0; // сила, действующая на шар
252 b1.vx = vx0; b1.vy = vy0; // начальная скорость
253 balls[n/2-(i+1)]=b;//[2*i]
254 balls[n/2+(i)] = b1;//[2*i+1]
255 }
256 context.clearRect(0, 0, w * scale, h * scale);
257 }
258 this.set_c_t = function(input)
259 {
260 c_t = Number(input);
261 B_4 = c_t;
262 time = 1;
263 for (i = 0;i<n/2;i++)
264 {
265 var b = [];
266 var b1 = [];
267 var time = 1;
268
269 b.fi_x = ugol*j; //угол с осью ОХ
270 b.omega=0;//угловая скорость
271 var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования.
272 j=j*(-1);
273 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара
274
275 b.Fx=0;b.Fy=0;
276 b.x_ = b.x; b.y_ = b.y;
277 b.fx = 0; b.fy = 0; // сила, действующая на шар
278 b.vx = vx0; b.vy = vy0; // начальная скорость
279 b1.fi_x = ugol*j; //угол с осью ОХ
280 b1.omega=0;
281 b1.Fx=0;b1.Fy=0;
282 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ; // расчетные координаты шара
283 b1.x_ = b.x; b1.y_ = b.y;
284 b1.fx = 0; b1.fy = 0; // сила, действующая на шар
285 b1.vx = vx0; b1.vy = vy0; // начальная скорость
286 balls[n/2-(i+1)]=b;//[2*i]
287 balls[n/2+(i)] = b1;//[2*i+1]
288 }
289 context.clearRect(0, 0, w * scale, h * scale);
290 }
291
292 slider_input.oninput = function() {
293 ugol = slider_input.value;
294 time = 1;
295 for (i = 0;i<n/2;i++)
296 {
297 var b = [];
298 var b1 = [];
299 var time = 1;
300 switch (f)
301 {
302 case 0:
303 b.fi_x = ugol*j;
304 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100);
305 j=j*(-1);
306 b1.fi_x = ugol*j; //угол с осью ОХ
307 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
308 break;
309 case 1:
310 if (i ==((n/2)-1))//закрепление края
311 {
312 b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0;
313 b.fi_x = 0;
314 b1.fi_x = ugol*j; //угол с осью ОХ
315 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
316 }
317 else
318 {
319 b.fi_x = ugol*j;
320 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара
321 j=j*(-1);
322 b1.fi_x = ugol*j; //угол с осью ОХ
323 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
324 }
325 break;
326 case 2:
327 if (i ==((n/2)-1))//закрепление краев
328 {
329 b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0;
330 b.fi_x = 0;
331 b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2.0;
332 b1.fi_x = 0;
333 }
334 else
335 {
336 b.fi_x = ugol*j;
337 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара
338 j=j*(-1);
339 b1.fi_x = ugol*j; //угол с осью ОХ
340 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
341 }
342 break;
343 }
344 var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования.
345 b.omega=0;
346 b.Fx=0;b.Fy=0;
347 b.x_ = b.x; b.y_ = b.y;
348 b.fx = 0; b.fy = 0; // сила, действующая на шар
349 b.vx = vx0; b.vy = vy0; // начальная скорость
350 b1.omega=0;
351 b1.Fx=0;b1.Fy=0;
352 b1.x_ = b.x; b1.y_ = b.y;
353 b1.fx = 0; b1.fy = 0; // сила, действующая на шар
354 b1.vx = vx0; b1.vy = vy0; // начальная скорость
355 balls[n/2-(i+1)]=b;//[2*i]
356 balls[n/2+(i)] = b1;//[2*i+1]
357
358 }
359 context.clearRect(0, 0, w * scale, h * scale);
360 };
361
362 slider_input_ox.oninput = function() {
363 sm_x = slider_input_ox.value;
364 time = 1;
365 j=1;
366 for (i = 0;i<n/2;i++)
367 {
368 var b = [];
369 var b1 = [];
370 var time = 1;
371 switch (f)
372 {
373 case 0:
374 b.fi_x = ugol*j;
375 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100);
376 j=j*(-1);
377 b1.fi_x = ugol*j; //угол с осью ОХ
378 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
379 break;
380 case 1:
381 if (i ==((n/2)-1))//закрепление края
382 {
383 b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0;
384 b.fi_x = 0;
385 b1.fi_x = ugol*j; //угол с осью ОХ
386 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
387 }
388 else
389 {
390 b.fi_x = ugol*j;
391 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара
392 j=j*(-1);
393 b1.fi_x = ugol*j; //угол с осью ОХ
394 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
395 }
396 break;
397 case 2:
398 if (i ==((n/2)-1))//закрепление краев
399 {
400 b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0;
401 b.fi_x = 0;
402 b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2.0;
403 b1.fi_x = 0;
404 }
405 else
406 {
407 b.fi_x = ugol*j;
408 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара
409 j=j*(-1);
410 b1.fi_x = ugol*j; //угол с осью ОХ
411 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
412 }
413 break;
414 }
415 b.omega=0;//угловая скорость
416 var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования.
417 b.Fx=0;b.Fy=0;
418 b.x_ = b.x; b.y_ = b.y;
419 b.fx = 0; b.fy = 0; // сила, действующая на шар
420 b.vx = vx0; b.vy = vy0; // начальная скорость
421 b1.omega=0;
422 b1.Fx=0;b1.Fy=0;
423 b1.x_ = b.x; b1.y_ = b.y;
424 b1.fx = 0; b1.fy = 0; // сила, действующая на шар
425 b1.vx = vx0; b1.vy = vy0; // начальная скорость
426 balls[n/2-(i+1)]=b;//[2*i]
427 balls[n/2+(i)] = b1;//[2*i+1]
428 }
429 context.clearRect(0, 0, w * scale, h * scale);
430 };
431
432 slider_input_oy.oninput = function() {
433 sm_y = slider_input_oy.value;
434 time = 1;
435 j=1;
436 for (i = 0;i<n/2;i++)
437 {
438 var b = [];
439 var b1 = [];
440 var time = 1;
441 switch (f)
442 {
443 case 0:
444 b.fi_x = ugol*j;
445 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100);
446 j=j*(-1);
447 b1.fi_x = ugol*j; //угол с осью ОХ
448 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
449 break;
450 case 1:
451 if (i ==((n/2)-1))//закрепление края
452 {
453 b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0;
454 b.fi_x = 0;
455 b1.fi_x = ugol*j; //угол с осью ОХ
456 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
457 }
458 else
459 {
460 b.fi_x = ugol*j;
461 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара
462 j=j*(-1);
463 b1.fi_x = ugol*j; //угол с осью ОХ
464 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
465 }
466 break;
467 case 2:
468 if (i ==((n/2)-1))//закрепление краев
469 {
470 b.x = (w / 2)-diag*(2*i+1)*1.0; b.y = h / 2.0;
471 b.fi_x = 0;
472 b1.x = (w / 2)+diag*(2*i+1)*1.0; b1.y = h / 2.0;
473 b1.fi_x = 0;
474 }
475 else
476 {
477 b.fi_x = ugol*j;
478 b.x = (w / 2)-diag*(2*i+1)*(1.0+sm_x/100); b.y = h / (2.00+sm_y/100); // расчетные координаты шара
479 j=j*(-1);
480 b1.fi_x = ugol*j; //угол с осью ОХ
481 b1.x = (w / 2)+diag*(2*i+1)*(1.0+sm_x/100); b1.y = h / (2.00-sm_y/100) ;
482 }
483 break;
484 }
485 b.omega=0;//угловая скорость
486 var dx = diag*Math.cos(b.fi_x*Math.PI/180);//смещение для рисования.
487 b.Fx=0;b.Fy=0;
488 b.x_ = b.x; b.y_ = b.y;
489 b.fx = 0; b.fy = 0; // сила, действующая на шар
490 b.vx = vx0; b.vy = vy0; // начальная скорость
491 b1.omega=0;
492 b1.Fx=0;b1.Fy=0;
493 b1.x_ = b.x; b1.y_ = b.y;
494 b1.fx = 0; b1.fy = 0; // сила, действующая на шар
495 b1.vx = vx0; b1.vy = vy0; // начальная скорость
496 balls[n/2-(i+1)]=b;//[2*i]
497 balls[n/2+(i)] = b1;//[2*i+1]
498
499 }
500 context.clearRect(0, 0, w * scale, h * scale);
501 };
502 // Функция, делающая spf шагов интегрирования
503 function physics()
504 { // то, что происходит каждый шаг времени
505 for (var s = 1; s <= spf; s++) //шаги интегрирования
506 {
507
508 for (i = 0;i<(n-1);i++)
509 {
510
511 d =[];
512 R = 1;
513 b = balls[i];//balls[2*i];
514 b1 = balls[i+1];//balls[2*i+1];
515 D = Math.sqrt((b.x-b1.x)*(b.x-b1.x)+(b.y-b1.y)*(b.y-b1.y));//Math.abs((b.x-b1.x));//Math.sqrt((b.x-b1.x)*(b.x-b1.x)+(b.y-b1.y)*(b.y-b1.y))-2*diag;
516 d.fi_x = 180*Math.asin((b1.y-b.y)/D)/3.14;
517 pr = 3.14/180;
518 fi = 180+b1.fi_x
519
520 //=============================================Силы=====================================
521 A = -Math.cos(inRad(fi))*Math.cos(inRad(d.fi_x))-Math.sin(inRad(fi))*Math.sin(inRad(d.fi_x))+Math.cos(inRad(b.fi_x))*Math.cos(inRad(d.fi_x))+Math.sin(inRad(b.fi_x))*Math.sin(inRad(d.fi_x));
522 b.Fx = B_1*(D-2*diag)*Math.cos(inRad(d.fi_x))+(B_2/2/D)*( Math.cos(inRad(fi))-Math.cos(inRad(b.fi_x))+A*Math.cos(inRad(d.fi_x)));
523 b1.Fx = -b.Fx;
524 b.Fy = B_1*(D-2*diag)*Math.sin(inRad(d.fi_x))+(B_2/2/D)*( Math.sin(inRad(fi))-Math.sin(inRad(b.fi_x))+A*Math.sin(inRad(d.fi_x)));
525 b1.Fy = -b.Fy;
526 M_tb = B_3*(Math.cos(inRad(fi))*Math.sin(inRad(b.fi_x))-Math.cos(inRad(b.fi_x))*Math.sin(inRad(fi)))-(B_4/2)*(Math.cos(inRad(fi-90))*Math.sin(inRad(b.fi_x+90))-Math.sin(inRad(fi-90))*Math.cos(inRad(b.fi_x+90)));
527 b.fx = R * (b.Fy*Math.cos(inRad(b.fi_x))-b.Fx*Math.sin(inRad(b.fi_x))) - (B_2/2) * (Math.cos(inRad(d.fi_x))*Math.sin(inRad(b.fi_x))-Math.sin(inRad(d.fi_x))*Math.cos(inRad(b.fi_x))) + M_tb;
528 b1.fx = R * (-Math.cos(inRad(fi))*b.Fy+Math.sin(inRad(fi))*b.Fx) + (B_2/2) * (Math.cos(inRad(d.fi_x))*Math.sin(inRad(fi))-Math.sin(inRad(d.fi_x))*Math.cos(inRad(fi)))- M_tb;
529
530 //======================================================================================
531 var J1 = 10000;
532 var m =1;
533 var beta_vr=0.00001//0.005;
534 var beta_x=0.5//1;
535 var beta_y=0.01//0.1;
536 //console.log(c_b);
537 if (f==0)//совбодное тело
538 {
539 x_v1=balls[i].vx;
540 y_v1=balls[i].vy;
541 x_v2=balls[i+1].vx;
542 y_v2=balls[i+1].vy;
543 vr1 = balls[i].omega;
544 vr2 = balls[i+1].omega;
545 balls[i] = b;
546 balls[i+1] = b1;
547 balls[i].omega+=J1*(balls[i].fx-beta_vr*vr1)*dt;
548 balls[i].vx+=m*(balls[i].Fx-beta_x*x_v1)*dt;
549 balls[i].vy+=m*(balls[i].Fy-beta_y*y_v1)*dt;
550 balls[i+1].omega+=J1*(balls[i+1].fx-beta_vr*vr2)*dt;
551 balls[i+1].vx+=m*(balls[i+1].Fx-beta_x*x_v2)*dt;
552 balls[i+1].vy+=m*(balls[i+1].Fy-beta_y*y_v2)*dt;
553 balls[i].y+=balls[i].vy*dt;
554 balls[i].fi_x+=balls[i].omega*dt;
555 balls[i].x+=balls[i].vx*dt;
556 balls[i+1].x+=balls[i+1].vx*dt;
557 balls[i+1].fi_x+=balls[i+1].omega*dt;
558 balls[i+1].y+=balls[i+1].vy*dt;
559 asd=balls[0].fx+balls[1].fx;
560 }
561 else//закрепелнный край
562 {
563 if (f==1)////закрепелнный край
564 {
565 balls[i] = b;
566 balls[i+1] = b1;
567 x_v1=balls[i].vx;
568 y_v1=balls[i].vy;
569 x_v2=balls[i+1].vx;
570 y_v2=balls[i+1].vy;
571 vr1 = balls[i].omega;
572 vr2 = balls[i+1].omega;
573 balls[i].omega+=J1*(balls[i].fx-beta_vr*vr1)*dt;
574 balls[i].vx+=m*(balls[i].Fx-beta_x*x_v1)*dt;
575 balls[i].vy+=m*(balls[i].Fy-beta_y*y_v1)*dt;
576 balls[i+1].omega+=J1*(balls[i+1].fx-beta_vr*vr2)*dt;
577 balls[i+1].vx+=m*(balls[i+1].Fx-beta_x*x_v2)*dt;
578 balls[i+1].vy+=m*(balls[i+1].Fy-beta_y*y_v2)*dt;
579 if (i>0)
580 {
581 balls[i].fi_x+=balls[i].omega*dt;
582 balls[i+1].y+=balls[i+1].vy*dt;
583 balls[i].y+=balls[i].vy*dt;
584 balls[i].x+=balls[i].vx*dt;
585 balls[i+1].x+=balls[i+1].vx*dt;
586 balls[i+1].fi_x+=balls[i+1].omega*dt;
587 }
588 }
589 else //оба края закрепелены
590 {
591
592 x_v1=balls[i].vx;
593 y_v1=balls[i].vy;
594 x_v2=balls[i+1].vx;
595 y_v2=balls[i+1].vy;
596 vr1 = balls[i].omega;
597 vr2 = balls[i+1].omega;
598 balls[i] = b;
599 balls[i+1] = b1;
600 balls[i].omega+=J1*(balls[i].fx-beta_vr*vr1)*dt;
601 balls[i].vx+=m*(balls[i].Fx-10*beta_x*x_v1)*dt;
602 balls[i].vy+=m*(balls[i].Fy-10*beta_y*y_v1)*dt;
603 balls[i+1].omega+=J1*(balls[i+1].fx-beta_vr*vr2)*dt;
604 balls[i+1].vx+=m*(balls[i+1].Fx-10*beta_x*x_v2)*dt;
605 balls[i+1].vy+=m*(balls[i+1].Fy-10*beta_y*y_v2)*dt;
606 if ((i>0)&&(i<(n-2)))
607 {
608 balls[i].fi_x+=balls[i].omega*dt;
609 balls[i+1].y+=balls[i+1].vy*dt;
610 balls[i].y+=balls[i].vy*dt;
611 balls[i].x+=balls[i].vx*dt;
612 balls[i+1].x+=balls[i+1].vx*dt;
613 balls[i+1].fi_x+=balls[i+1].omega*dt;
614 }
615
616 }
617 }
618
619 }
620
621 time = time + 1;
622 }
623 }
624 // определение функции, вычисляющей силу
625
626 // определение функции, рисующией частицу, стенки и пр
627 context.fillStyle = "#3070d0"; // цвет
628 //===================================Взаимодествие мышью========================
629 // функция запускается при нажатии клавиши мыши
630 canvasBalls.onmousedown = function(e) {
631 var m = mouseCoords(e); // получаем координаты курсора мыши
632 switch (f)
633 {
634 case(0):
635 var x = balls[n-1].x - m.x/scale; // расстояние от центра шара до курсора по оси x
636 var y = balls[n-1].y - m.y/scale; // расстояние от центра шара до курсора по оси y
637 var rLen2 = x * x + y * y; // квадрат расстояния между курсором и центром шара
638 if (rLen2 <= diag*diag) { // если курсор нажал на шар
639 xShift = balls[n-1].x - m.x/scale; // сдвиг курсора относительно центра шара по x
640 yShift = balls[n-1].y - m.y/scale; // сдвиг курсора относительно центра шара по y
641 canvasBalls.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения
642 }
643 break;
644 case(1):
645 var x = balls[n-1].x - m.x/scale; // расстояние от центра шара до курсора по оси x
646 var y = balls[n-1].y - m.y/scale; // расстояние от центра шара до курсора по оси y
647 var rLen2 = x * x + y * y; // квадрат расстояния между курсором и центром шара
648 if (rLen2 <= diag*diag) { // если курсор нажал на шар
649 xShift = balls[n-1].x - m.x/scale; // сдвиг курсора относительно центра шара по x
650 yShift = balls[n-1].y - m.y/scale; // сдвиг курсора относительно центра шара по y
651 canvasBalls.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения
652 }
653 break;
654 case (2):
655 case(0):
656 var x = balls[n/2].x - m.x/scale; // расстояние от центра шара до курсора по оси x
657 var y = balls[n/2].y - m.y/scale; // расстояние от центра шара до курсора по оси y
658 var rLen2 = x * x + y * y; // квадрат расстояния между курсором и центром шара
659 if (rLen2 <= diag*diag) { // если курсор нажал на шар
660 xShift = balls[n/2].x - m.x/scale; // сдвиг курсора относительно центра шара по x
661 yShift = balls[n/2].y - m.y/scale; // сдвиг курсора относительно центра шара по y
662 canvasBalls.onmousemove = mouseMove; // пока клавиша нажата - работает функция перемещения
663 }
664 break;
665 }
666 };
667
668 // функция запускается при отпускании клавиши мыши
669 document.onmouseup = function() {
670 canvasBalls.onmousemove = null; // когда клавиша отпущена - функции перемещения нету
671 };
672
673 // функция запускается при перемещении мыши (много раз, в каждый момент перемещения)
674 // в нашем случае работает только с зажатой клавишей мыши
675 function mouseMove(e) {
676 switch (f)
677 {
678 case(0):
679 var m = mouseCoords(e); // получаем координаты курсора мыши
680 balls[n-1].x = m.x/scale + xShift;
681 balls[n-1].y = m.y/scale+ yShift;
682 draw();
683 break;
684 case(1):
685 var m = mouseCoords(e);
686 x_nach =(w / 2)+diag*(n/2+2)*1.0;
687 y_nach = h / 2.0;
688 r_nach = Math.sqrt(x_nach*x_nach+y_nach*y_nach);
689 r_m = Math.sqrt(((m.x/scale-2*diag)-x_nach)*((m.x/scale-2*diag)-x_nach)+((m.y/scale)-y_nach)*((m.y/scale)-y_nach));
690 console.log(x_nach);
691 console.log(m.x/scale);
692 //console.log(r_nach);
693 if (Math.abs(r_m)<(3*diag)) // получаем координаты курсора мыши
694 {pr_x = m.x/scale + xShift*0.01 -balls[n-1].x;
695 pr_y = m.y/scale+yShift-balls[n-1].y;
696 balls[n-1].x = m.x/scale + xShift*0.0001;
697 balls[n-1].y = m.y/scale+ yShift;
698 }
699 draw();
700 break;
701 case(2):
702 var m = mouseCoords(e); // получаем координаты курсора мыши
703 balls[n/2].x = m.x/scale + xShift;
704 balls[n/2].y = m.y/scale+ yShift;
705 draw();
706 break;
707 }
708 }
709
710 // функция возвращает координаты курсора мыши
711 function mouseCoords(e) {
712 var m = [];
713 var rect = canvasBalls.getBoundingClientRect();
714 m.x = e.clientX - rect.left;
715 m.y = e.clientY - rect.top;
716 //console.log(m.x/scale);
717 //console.log(balls[n-1].x);
718 return m;
719 }
720
721 function inRad(num)
722 {
723 return num * Math.PI / 180;
724 }
725
726 function draw()
727 {
728 context.clearRect(0, 0, w * scale, h * scale); // очистить экран
729 for (var i =0;i<n;i++)
730 {
731 b = balls[i];
732 context.beginPath();
733 context.translate(b.x*scale,b.y * scale);//перенос в центр
734 context.rotate(inRad(b.fi_x-45));
735 context.fillRect(-rectW/2, -rectH/2, rectW, rectH);
736 context.rotate(-inRad(b.fi_x-45));
737 context.translate(-b.x * scale, -b.y * scale);//перенос обратно
738 context.closePath();
739 context.stroke();
740 }
741 }
742 }
Файл "v-model.html"
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title> Particle </title>
5 <script src="V_model.js"></script>
6 </head>
7 <body>
8 <!-- Добавление области для рисования частицы -->
9 <canvas id="canvasBalls" width="800" height="400" style="border:1px solid #000000;"></canvas>
10
11 <div>
12 c_a =
13 <input id="Text_vx0" value = "100" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
14 if (!this.checkValidity()) return;
15 app.set_c_a(this.value);
16 <!-- document.getElementById('Slider_02').value = this.value; -->
17 ">
18 <!-- Добавление слайдера -->
19 <!-- <input type="range" id="Slider_02" style="width: 100px;" oninput="app.set_02(this.value); document.getElementById('Text_02').value = this.value;"> -->
20 </I></font>
21 c_b =
22 <input id="Text_vx0" value = "0.1" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
23 if (!this.checkValidity()) return;
24 app.set_c_b(this.value);
25 <!-- document.getElementById('Slider_02').value = this.value; -->
26 ">
27 <!-- Добавление слайдера -->
28 <!-- <input type="range" id="Slider_02" style="width: 100px;" oninput="app.set_02(this.value); document.getElementById('Text_02').value = this.value;"> -->
29 </I></font>
30 c_d =
31 <input id="Text_vx0" value = "100" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
32 if (!this.checkValidity()) return;
33 app.set_c_d(this.value);
34 <!-- document.getElementById('Slider_02').value = this.value; -->
35 ">
36 <!-- Добавление слайдера -->
37 <!-- <input type="range" id="Slider_02" style="width: 100px;" oninput="app.set_02(this.value); document.getElementById('Text_02').value = this.value;"> -->
38 </I></font>
39 c_t =
40 <input id="Text_vx0" value = "1" style="width: 4.2ex;" required pattern="[-+]?([0-9]*\.[0-9]+|[0-9]+)" oninput="
41 if (!this.checkValidity()) return;
42 app.set_c_t(this.value);
43 <!-- document.getElementById('Slider_02').value = this.value; -->
44 ">
45 <!-- Добавление слайдера -->
46 <!-- <input type="range" id="Slider_02" style="width: 100px;" oninput="app.set_02(this.value); document.getElementById('Text_02').value = this.value;"> -->
47 </I></font>
48 <input type="button" name="" onclick="
49 app.new_start();" value="restart"/></div>
50 <div><input type="radio" id="radio_pic_1" name="pic" checked /> Free body
51 <input type="radio" id="radio_pic_2" name="pic" /> Fixed edge
52 <input type="radio" id="radio_pic_3" name="pic" /> Fixed edges <br></div>
53 <div>Angle of torsion
54 0
55 <input type="range" id="slider_input" min=0 max=40 value=0 step=0.5 style="width: 200px;">40
56 <div>Shear OX
57 0
58 <input type="range" id="slider_input_ox" min=0 max=10 value=0 step=0.5 style="width: 200px;">10</div>
59 <div>Shear OY
60 0
61 <input type="range" id="slider_input_oy" min=0 max=10 value=0 step=0.5 style="width: 200px;">10</div>
62 <script type="text/javascript"> app = new MainParticle(document.getElementById('canvasBalls'));
63 </script>
64 </body>
65 </html>