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

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