Цепочка частиц с V-model взаимодействием — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Реализации цепочки)
(Реализации цепочки)
Строка 59: Строка 59:
 
Приведенная ниже программа реализует цепочку частиц, взаимодействие между которыми является V - model.
 
Приведенная ниже программа реализует цепочку частиц, взаимодействие между которыми является V - model.
  
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Lapin/v_model.html |width=1200 |height=600 |border=0 }}
+
{{#widget:Iframe |url=http://tm.spbstu.ru/htmlets/Lapin/v_model.html |width=1200 |height=450 |border=0 }}
  
 
Скачать [[Медиа:V-model.zip|V-model]].  
 
Скачать [[Медиа:V-model.zip|V-model]].  

Версия 16:31, 19 января 2015

Виртуальная лаборатория > Цепочка частиц с V-model взаимодействием

Краткое описание V - model

V-model используется для описания сыпучих твердых тел, например горных пород, керамики, бетона, нанокомпозитов и агломератов.

Модель описывается следующими формулами:

Взаимодействие двух частиц

Сила взаимодействия:

[math]\mathbf{F_{ij}} = B_1 ( D_{ij} - a) \mathbf{d_{ij}} + \frac{B_2}{2D_{ij}}(\mathbf{n_{j1}} - \mathbf{n_{i1}})\cdot(\mathbf{E}-\mathbf{d_{ij}}\mathbf{d_{ij}}) [/math]

Моменты:

[math]\mathbf{M_{ij}} = R_i \mathbf{n_{i1}} \times \mathbf{F_{ij}} - \frac{B_2}{2}\mathbf{d_{ij}}\times \mathbf{n_{i1}}+\mathbf{M_{tb}} [/math]

[math]\mathbf{M_{ji}} = R_i \mathbf{n_{j1}} \times \mathbf{F_{ji}} + \frac{B_2}{2}\mathbf{d_{ij}}\times \mathbf{n_{j1}}-\mathbf{M_{tb}} [/math]

[math]\mathbf{M_{tb}} = B_3 \mathbf{n_{j1}} \times \mathbf{n_{i1}} - \frac{B_4}{2}(\mathbf{n_{j2}}\times \mathbf{n_{i2}}+\mathbf{n_{j3}}\times \mathbf{n_{i3}}) [/math]

Где [math]B_1[/math], [math]B_2[/math], [math]B_3[/math] и [math]B_4[/math] - различные коэффициенты, которые являются характеристиками системы.


Описание реализации цепочки

Виды деформаций

В программе реализованы три различных граничных условия, которые могут выбраны пользователем:

  • Свободная цепочка
  • Цепочка с зажатым левым краем
  • Цепочка с зажатыми краями

Так же пользователь в первых двух случаях может перемещать крайнюю правую частицу, а в третьем случае может двигать центральную правую частицу.

Предусмотрена возможность задавать начальные условия для всей цепочки:

  • Задавать угол закручивания частиц друг относительно друга.
  • Задавать относительное смещение частиц вдоль оси OX
  • Задавать относительное смещение частиц вдоль оси OY

Так же есть возможность задавать коэффициенты жесткости системы на различные движения. Которые связаны с коэффициентами из указанных выше формул для V - model.

  • Жесткость на растяжение-сжатие: [math]c_a = B_1 [/math]
  • Жесткость на сдвиг: [math]c_d = \frac{B_2}{a^2} [/math]
  • Жесткость на изгиб: [math]c_b = \frac{B_2}{4} + B_3 +\frac{B_4}{2} [/math]
  • Жесткость на кручение: [math]c_t = B_4 [/math]

Реализации цепочки

Приведенная ниже программа реализует цепочку частиц, взаимодействие между которыми является V - model.

Скачать V-model.

Текст программы на языке JavaScript (разработчик Лапин Руслан):

Файл "V-model.js" <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default">

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(); 
			}
    }
}

</toggledisplay> Файл "v-model.html" <toggledisplay status=hide showtext="Показать↓" hidetext="Скрыть↑" linkstyle="font-size:default">

 <!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>

</toggledisplay>