Взаимодействие частиц (JavaScript) — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
(Новая страница: «'''Исполнители:''' [http://tm.spbstu.ru/%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2%D0%B0_%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0 Егоров…»)
 
(Скрипт)
 
(не показаны 3 промежуточные версии этого же участника)
Строка 1: Строка 1:
'''Исполнители:''' [http://tm.spbstu.ru/%D0%95%D0%B3%D0%BE%D1%80%D0%BE%D0%B2%D0%B0_%D0%95%D0%BA%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B0 Егорова Екатерина], Эдель Мария <br>
+
'''Исполнители:''' [[ Егорова Екатерина]], [[Эдель Мария]] <br>
 
'''Группа:''' 3630103/90003 <br>
 
'''Группа:''' 3630103/90003 <br>
 
'''Семестр:''' весна 2020 года.<br>
 
'''Семестр:''' весна 2020 года.<br>
Строка 6: Строка 6:
 
Построить модель взаимодействия падающей частицы и препятствия в виде N неподвижных частиц.
 
Построить модель взаимодействия падающей частицы и препятствия в виде N неподвижных частиц.
 
== Математическая модель ==
 
== Математическая модель ==
В данной работе при подсчете сил взаимодействия частиц применялась модель парного силового [http://tm.spbstu.ru/%D0%9F%D0%BE%D1%82%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB_%D0%9B%D0%B5%D0%BD%D0%BD%D0%B0%D1%80%D0%B4-%D0%94%D0%B6%D0%BE%D0%BD%D1%81%D0%B0 потенциала взаимодействия Леннарда Джонса], описывающая зависимость энергии взаимодействия двух частиц от расстояния между ними.<br>
+
В данной работе при подсчете сил взаимодействия частиц применялась модель парного силового [http://tm.spbstu.ru/%D0%9F%D0%BE%D1%82%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB_%D0%9B%D0%B5%D0%BD%D0%BD%D0%B0%D1%80%D0%B4-%D0%94%D0%B6%D0%BE%D0%BD%D1%81%D0%B0 потенциала взаимодействия Леннарда Джонса], описывающая зависимость энергии взаимодействия двух частиц от расстояния между ними.Эта модель позволяет достаточно реалистично передать свойства реального взаимодействия сферических неполярных молекул.<br>
Потенциал Леннарда Джонса описывается формулой: ((#widget:Iframe | url=http://tm.spbstu.ru/htmlets/js2020/Egorova/form.png | width=382 | height=157 | border=0))
+
Парный силовой потенциал взаимодействия определяется формулой: <br>
 +
{{#widget: Iframe | url=http://tm.spbstu.ru/htmlets/js2020/Egorova/form.png | width=382 | height=175 | border=0}}
 +
 
 +
'''Входные данные'''<br>
 +
*Радиус падающего шарика: 20px
 +
*Масса падающего шарика: 50
 +
*Всего частиц: 160
 +
 
 +
== Визуализация ==
 +
{{#widget: Iframe | url=http://tm.spbstu.ru/htmlets/js2020/Egorova/mindex.html | width=700 | height=600 | border=0}}
 +
 
 +
==Скрипт==
 +
<div class="mw-collapsible mw-collapsed">
 +
'''Код программы на языке JavaScript:''' <div class="mw-collapsible-content">
 +
<syntaxhighlight lang="javascript" line start="1" enclose="div">
 +
window.addEventListener('load', main, false);
 +
function main(){
 +
 
 +
var ctx = canvas_example.getContext('2d');
 +
var w = canvas_example.width;
 +
var h = canvas_example.height;
 +
 
 +
 
 +
function ball(x, y, r, m, Fx, Fy) {
 +
this.x = x;
 +
this.y = y;
 +
this.vx = 0;
 +
this.vy = 0;
 +
this.r = r;
 +
this.m = m;
 +
this.Fx = Fx;
 +
this.Fy = Fy;
 +
}
 +
 
 +
 +
 +
var X_c = w/2;
 +
var Y_c = h/3;
 +
var Vy_c = 0;
 +
 
 +
var balls = [];
 +
var r = 10;
 +
 +
 +
for (var i=0; i<27; i++) {
 +
balls.push(new ball(r+(w)*(i/27), h-r, r, 1, 0, 0));
 +
}
 +
for (var i=0; i<26; i++) {
 +
balls.push(new ball(2*r+(w)*(i/27), h-3*r, r, 1, 0, 0));
 +
}
 +
for (var i=0; i<27; i++) {
 +
balls.push(new ball(r+(w)*(i/27), h-5*r, r, 1, 0, 0));
 +
}
 +
for (var i=0; i<26; i++) {
 +
balls.push(new ball(2*r+(w)*(i/27), h-7*r, r, 1, 0, 0));
 +
}
 +
for (var i=0; i<27; i++) {
 +
balls.push(new ball(r+(w)*(i/27), h-9*r, r, 1, 0, 0));
 +
}
 +
for (var i=0; i<26; i++) {
 +
balls.push(new ball(2*r+(w)*(i/27), h-11*r, r, 1, 0, 0));
 +
}
 +
for (var i=0; i<27; i++) {
 +
balls.push(new ball(r+(w)*(i/27), h-13*r, r, 1, 0, 0));
 +
}
 +
 +
/*console.log(radius(R));
 +
console.log(svyaz(D));
 +
 +
start.onclick = function() {
 +
R = radius();
 +
D = svyaz();*/
 +
 +
 +
var r_ball = new ball(X_c, Y_c, R, 50, 0, 0)
 +
r_ball.vy = 20;
 +
var N = 159;
 +
var a = 40;
 +
var dt = 0.001;
 +
var g = 1;
 +
 +
 +
 +
function draw() {
 +
ctx.clearRect(0,0,w,h);
 +
for (var i=0; i<N; i++) {
 +
ctx.beginPath();
 +
ctx.arc(balls[i].x, balls[i].y, balls[i].r, 0, 2*Math.PI);
 +
ctx.fillStyle = '#FF4500'
 +
ctx.stroke();
 +
ctx.fill();
 +
 
 +
}
 +
 
 +
 +
ctx.beginPath();
 +
ctx.fillStyle = '#0000FF'
 +
ctx.strokeStyle = '#000000';
 +
ctx.arc(r_ball.x, r_ball.y, r_ball.r, 0, 2*Math.PI);
 +
ctx.stroke();
 +
ctx.fill();
 +
 +
}
 +
 
 +
 +
 
 +
function phys() {
 +
// обнуляем силы шариков
 +
for (var i=0; i<N; i++) {
 +
balls[i].Fx = 0;
 +
balls[i].Fy = 0;
 +
}
 +
r_ball.Fx = 0;
 +
r_ball.Fy = 0;
 +
// считаем силы
 +
for (var i=0; i<N-1; i++) {
 +
for (var j=i+1; j<N; j++) {
 +
var a = balls[i].r+balls[j].r;
 +
var r2 = (balls[i].x-balls[j].x)*(balls[i].x-balls[j].x)+(balls[i].y-balls[j].y)*(balls[i].y-balls[j].y);
 +
var Fx = 12*D/a/a*(Math.pow(a, 14)/Math.pow(r2, 7)-Math.pow(a, 8)/Math.pow(r2, 4))*(balls[i].x-balls[j].x);
 +
var Fy = 12*D/a/a*(Math.pow(a, 14)/Math.pow(r2, 7)-Math.pow(a, 8)/Math.pow(r2, 4))*(balls[i].y-balls[j].y);
 +
balls[i].Fx += Fx/balls[i].m;
 +
balls[i].Fy += Fy/balls[i].m;
 +
balls[j].Fx -= Fx/balls[j].m;
 +
balls[j].Fy -= Fy/balls[j].m;
 +
}
 +
var a = balls[i].r+r_ball.r;
 +
var r2 = (balls[i].x-r_ball.x)*(balls[i].x-r_ball.x)+(balls[i].y-r_ball.y)*(balls[i].y-r_ball.y);
 +
if (r2<a*a) {
 +
var Fx = 12*D/a*(Math.pow(a, 14)/Math.pow(r2, 7)-Math.pow(a, 8)/Math.pow(r2, 4))*(balls[i].x-r_ball.x);
 +
var Fy = 12*D/a*(Math.pow(a, 14)/Math.pow(r2, 7)-Math.pow(a, 8)/Math.pow(r2, 4))*(balls[i].y-r_ball.y);
 +
balls[i].Fx += Fx/balls[i].m;
 +
balls[i].Fy += Fy/balls[i].m;
 +
r_ball.Fx -= Fx/r_ball.m;
 +
r_ball.Fy -= Fy/r_ball.m;
 +
}
 +
}
 +
 +
// двигаем шарики
 +
for (var i=0; i<N; i++) {
 +
balls[i].vx += balls[i].Fx*dt;
 +
balls[i].vy += (balls[i].Fy+g)*dt;
 +
balls[i].x += balls[i].vx*dt;
 +
balls[i].y += balls[i].vy*dt;
 +
 +
if (balls[i].y < r) {
 +
balls[i].y = r;
 +
}
 +
 +
if (balls[i].y > h-r) {
 +
balls[i].y = h-r;
 +
}
 +
 +
if (balls[i].x>w-r) {
 +
balls[i].x = w-r;
 +
}
 +
 +
if (balls[i].x<r) {
 +
balls[i].x = r;
 +
}
 +
var betta = 0.7;
 +
r_ball.vx += (r_ball.Fx-betta*r_ball.vx)*dt;
 +
r_ball.vy += (r_ball.Fy+g-betta*r_ball.vy)*dt;
 +
r_ball.x += r_ball.vx*dt;
 +
r_ball.y += r_ball.vy*dt;
 +
 +
if (r_ball.y < r) {
 +
r_ball.vy *=-1;
 +
}
 +
 +
if (r_ball.y > h-20) {
 +
r_ball.vy *=-1;
 +
}
 +
 +
if (r_ball.x>w-20) {
 +
r_ball.vx *=-1;
 +
}
 +
 +
if (r_ball.x<20) {
 +
r_ball.vx *=-1;
 +
}
 +
}
 +
}
 +
 
 +
 
 +
draw();
 +
 
 +
function control() {
 +
phys();
 +
draw();
 +
}
 +
 
 +
var timer = setInterval(control, 10);
 +
}
 +
}
 +
 +
 
 +
</syntaxhighlight>
 +
</div>

Текущая версия на 21:56, 1 июня 2020

Исполнители: Егорова Екатерина, Эдель Мария
Группа: 3630103/90003
Семестр: весна 2020 года.

Постановка задачи[править]

Построить модель взаимодействия падающей частицы и препятствия в виде N неподвижных частиц.

Математическая модель[править]

В данной работе при подсчете сил взаимодействия частиц применялась модель парного силового потенциала взаимодействия Леннарда Джонса, описывающая зависимость энергии взаимодействия двух частиц от расстояния между ними.Эта модель позволяет достаточно реалистично передать свойства реального взаимодействия сферических неполярных молекул.
Парный силовой потенциал взаимодействия определяется формулой:

Входные данные

  • Радиус падающего шарика: 20px
  • Масса падающего шарика: 50
  • Всего частиц: 160

Визуализация[править]

Скрипт[править]

Код программы на языке JavaScript:
  1 window.addEventListener('load', main, false); 
  2 function main(){ 
  3 
  4 	var ctx = canvas_example.getContext('2d'); 
  5 	var w = canvas_example.width; 
  6 	var h = canvas_example.height; 
  7 
  8 
  9 	function ball(x, y, r, m, Fx, Fy) { 
 10 		this.x = x; 
 11 		this.y = y; 
 12 		this.vx = 0; 
 13 		this.vy = 0; 
 14 		this.r = r; 
 15 		this.m = m; 
 16 		this.Fx = Fx; 
 17 		this.Fy = Fy; 
 18 	} 
 19 
 20 		
 21 		
 22 	var X_c = w/2; 
 23 	var Y_c = h/3; 
 24 	var Vy_c = 0; 
 25 
 26 	var balls = []; 
 27 	var r = 10;
 28 	
 29 	
 30 	for (var i=0; i<27; i++) { 
 31 		balls.push(new ball(r+(w)*(i/27), h-r, r, 1, 0, 0)); 
 32 	} 
 33 	for (var i=0; i<26; i++) { 
 34 		balls.push(new ball(2*r+(w)*(i/27), h-3*r, r, 1, 0, 0)); 
 35 	} 
 36 	for (var i=0; i<27; i++) { 
 37 		balls.push(new ball(r+(w)*(i/27), h-5*r, r, 1, 0, 0)); 
 38 	} 
 39 	for (var i=0; i<26; i++) { 
 40 		balls.push(new ball(2*r+(w)*(i/27), h-7*r, r, 1, 0, 0)); 
 41 	} 
 42 	for (var i=0; i<27; i++) { 
 43 		balls.push(new ball(r+(w)*(i/27), h-9*r, r, 1, 0, 0)); 
 44 	} 
 45 	for (var i=0; i<26; i++) { 
 46 		balls.push(new ball(2*r+(w)*(i/27), h-11*r, r, 1, 0, 0)); 
 47 	} 
 48 	for (var i=0; i<27; i++) { 
 49 		balls.push(new ball(r+(w)*(i/27), h-13*r, r, 1, 0, 0)); 
 50 	} 
 51 	
 52 	/*console.log(radius(R));
 53 		console.log(svyaz(D));
 54 	
 55 		start.onclick = function() {
 56 	R = radius();
 57 	D = svyaz();*/
 58 	
 59 	
 60 	var r_ball = new ball(X_c, Y_c, R, 50, 0, 0)
 61 	r_ball.vy = 20;
 62 	var N = 159; 
 63 	var a = 40; 
 64 	var dt = 0.001;
 65 	var g = 1;
 66 	
 67 	
 68 		
 69 	function draw() { 
 70 	ctx.clearRect(0,0,w,h); 
 71 		for (var i=0; i<N; i++) { 
 72 		ctx.beginPath(); 
 73 		ctx.arc(balls[i].x, balls[i].y, balls[i].r, 0, 2*Math.PI); 
 74 		ctx.fillStyle = '#FF4500'
 75 		ctx.stroke(); 
 76 		ctx.fill();
 77 
 78 		} 
 79 
 80 		
 81 		ctx.beginPath();
 82 		ctx.fillStyle = '#0000FF'
 83 		ctx.strokeStyle = '#000000'; 
 84 		ctx.arc(r_ball.x, r_ball.y, r_ball.r, 0, 2*Math.PI); 
 85 		ctx.stroke(); 
 86 		ctx.fill();
 87 		
 88 	} 
 89 
 90  
 91 
 92 	function phys() { 
 93 		// обнуляем силы шариков
 94 		for (var i=0; i<N; i++) { 
 95 			balls[i].Fx = 0;
 96 			balls[i].Fy = 0;
 97 		}
 98 		r_ball.Fx = 0;
 99 		r_ball.Fy = 0;
100 		// считаем силы
101 		for (var i=0; i<N-1; i++) { 
102 			for (var j=i+1; j<N; j++) { 
103 				var a = balls[i].r+balls[j].r;
104 				var r2 = (balls[i].x-balls[j].x)*(balls[i].x-balls[j].x)+(balls[i].y-balls[j].y)*(balls[i].y-balls[j].y); 
105 				var Fx = 12*D/a/a*(Math.pow(a, 14)/Math.pow(r2, 7)-Math.pow(a, 8)/Math.pow(r2, 4))*(balls[i].x-balls[j].x); 
106 				var Fy = 12*D/a/a*(Math.pow(a, 14)/Math.pow(r2, 7)-Math.pow(a, 8)/Math.pow(r2, 4))*(balls[i].y-balls[j].y); 
107 				balls[i].Fx += Fx/balls[i].m;
108 				balls[i].Fy += Fy/balls[i].m;
109 				balls[j].Fx -= Fx/balls[j].m;
110 				balls[j].Fy -= Fy/balls[j].m;
111 			}
112 			var a = balls[i].r+r_ball.r;
113 			var r2 = (balls[i].x-r_ball.x)*(balls[i].x-r_ball.x)+(balls[i].y-r_ball.y)*(balls[i].y-r_ball.y);
114 			if (r2<a*a) {
115 				var Fx = 12*D/a*(Math.pow(a, 14)/Math.pow(r2, 7)-Math.pow(a, 8)/Math.pow(r2, 4))*(balls[i].x-r_ball.x); 
116 				var Fy = 12*D/a*(Math.pow(a, 14)/Math.pow(r2, 7)-Math.pow(a, 8)/Math.pow(r2, 4))*(balls[i].y-r_ball.y);
117 				balls[i].Fx += Fx/balls[i].m;
118 				balls[i].Fy += Fy/balls[i].m;
119 				r_ball.Fx -= Fx/r_ball.m;
120 				r_ball.Fy -= Fy/r_ball.m;
121 			}
122 		} 
123 		
124 		// двигаем шарики
125 		for (var i=0; i<N; i++) { 
126 			balls[i].vx += balls[i].Fx*dt; 
127 			balls[i].vy += (balls[i].Fy+g)*dt; 
128 			balls[i].x += balls[i].vx*dt; 
129 			balls[i].y += balls[i].vy*dt; 
130 			
131 			if (balls[i].y < r) { 
132 				balls[i].y = r; 
133 			} 
134 			
135 			if (balls[i].y > h-r) { 
136 				balls[i].y = h-r; 
137 			} 
138 			
139 			if (balls[i].x>w-r) { 
140 				balls[i].x = w-r; 
141 			} 
142 			
143 			if (balls[i].x<r) { 
144 				balls[i].x = r; 
145 			} 
146 			var betta = 0.7;
147 			r_ball.vx += (r_ball.Fx-betta*r_ball.vx)*dt; 
148 			r_ball.vy += (r_ball.Fy+g-betta*r_ball.vy)*dt; 
149 			r_ball.x += r_ball.vx*dt; 
150 			r_ball.y += r_ball.vy*dt; 	
151 			
152 			if (r_ball.y < r) { 
153 				r_ball.vy *=-1; 
154 			} 
155 			
156 			if (r_ball.y > h-20) { 
157 				r_ball.vy *=-1;
158 			} 
159 			
160 			if (r_ball.x>w-20) { 
161 				r_ball.vx *=-1;
162 			} 
163 			
164 			if (r_ball.x<20) { 
165 				r_ball.vx *=-1; 
166 			} 
167 		} 
168 	} 
169 
170 
171 	draw(); 
172 
173 	function control() { 
174 		phys(); 
175 		draw(); 
176 	} 
177 
178 	var timer = setInterval(control, 10); 
179 }
180 }