Участник:StarfloFr — различия между версиями
StarfloFr (обсуждение | вклад) м |
StarfloFr (обсуждение | вклад) м |
||
Строка 1: | Строка 1: | ||
{{#widget:Iframe | url=http://tm.spbstu.ru/htmlets/js2020/Natalin/Kursach1.html | width=1920 | height=1080 | border=0}} | {{#widget:Iframe | url=http://tm.spbstu.ru/htmlets/js2020/Natalin/Kursach1.html | width=1920 | height=1080 | border=0}} | ||
+ | |||
+ | == КОД == | ||
+ | <!DOCTYPE html> | ||
+ | <html lang="ru"> | ||
+ | <head> | ||
+ | <title>Модель броуновского движения</title> | ||
+ | <meta charset="UTF-8"> | ||
+ | |||
+ | |||
+ | </head> | ||
+ | |||
+ | <style> | ||
+ | canvas { border: 1px solid black; } | ||
+ | .pr { | ||
+ | |||
+ | border-bottom :1px solid #a2a9b1; | ||
+ | |||
+ | </style> | ||
+ | <body onload = "start();" > | ||
+ | |||
+ | |||
+ | <p class = "pr" ; style='font-size:30px ; font-weight:40; font-family:'Linux Libertine','Georgia','Times',serif;'>Модель Броуновского движения</p> | ||
+ | |||
+ | <p class = "pr" ; style='font-size:23px ; font-weight:40; font-family:'Linux Libertine','Georgia','Times',serif;'>Описание</p> | ||
+ | <p style='font-size:18px ; font-weight:40; font-family:'Linux Libertine','Georgia','Times',serif;'>Модель Броуновского движения с изоброжением траектории. Работа сделана на языке программирования JavaScript.</p> | ||
+ | <p style='font-size:18px ; font-weight:40; font-family:'Linux Libertine','Georgia','Times',serif;'>Исполнитель: Никита Натальин.</p> | ||
+ | <p style='font-size:18px ; font-weight:40; font-family:'Linux Libertine','Georgia','Times',serif;'>Группа:3630103/90001</p> | ||
+ | |||
+ | |||
+ | <p class = "pr" ; style='font-size:23px ; font-weight:40; font-family:'Linux Libertine','Georgia','Times',serif;'>Визуализация</p> | ||
+ | |||
+ | <br> | ||
+ | <input type="text" id="size" value="500"> | ||
+ | |||
+ | <input type="button" value="chaneg size" onclick="changeSize();"> | ||
+ | <br> | ||
+ | <input type="text" id="addCount" value="10"> | ||
+ | <input type="button" value="add" onclick="add();"> | ||
+ | |||
+ | <input type="button" value="delete" onclick="del();"> | ||
+ | <br> | ||
+ | |||
+ | <input type="text" id="weight" value="500"> | ||
+ | <input type="button" value="weight" onclick="weight();"> | ||
+ | <br> | ||
+ | |||
+ | <input type="button" value="slowly" onclick="slowly();"> | ||
+ | <input type="button" value="faster" onclick="faster();"> | ||
+ | |||
+ | <br> | ||
+ | |||
+ | |||
+ | |||
+ | <label><input type="checkbox" id="color" checked>color</label> | ||
+ | <br><br> | ||
+ | |||
+ | |||
+ | <canvas id="GG" width="500" height="500"></canvas> | ||
+ | <script> | ||
+ | |||
+ | class Ball { | ||
+ | constructor(x, y, r, vx, vy,color){ | ||
+ | this.x = x; | ||
+ | this.y = y; | ||
+ | this.r = r; | ||
+ | this.vx = vy; | ||
+ | this.vy = vx; | ||
+ | |||
+ | this.calculateMass(); | ||
+ | |||
+ | this.color = color; | ||
+ | } | ||
+ | |||
+ | calculateMass() { | ||
+ | this.m = (this.r * this.r * this.r)/50 ; | ||
+ | } | ||
+ | |||
+ | getVx() { | ||
+ | return this.vx * Math.pow(2, timeSpeed); | ||
+ | } | ||
+ | |||
+ | getVy() { | ||
+ | return this.vy * Math.pow(2, timeSpeed); | ||
+ | } | ||
+ | |||
+ | move() { | ||
+ | this.x += this.getVx(); | ||
+ | this.y += this.getVy(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | var count = 50; | ||
+ | |||
+ | var MAX_SPEED = 20; | ||
+ | var MIN_RADIUS = 100; | ||
+ | var MAX_RADIUS = 100; | ||
+ | var WIDTH = 10000; | ||
+ | |||
+ | var timeSpeed = 0; | ||
+ | |||
+ | var balls = []; | ||
+ | |||
+ | var canvas; | ||
+ | var ctx; | ||
+ | var T = 300; | ||
+ | var pathx = []; | ||
+ | var pathy = []; | ||
+ | |||
+ | function random(min, max) { | ||
+ | return Math.random() * (max - min) + min; | ||
+ | } | ||
+ | |||
+ | function move() { | ||
+ | |||
+ | for (var i = 0; i < count; i++) { | ||
+ | var ball = balls[i]; | ||
+ | |||
+ | if (ball.x < ball.r && ball.vx < 0) | ||
+ | ball.vx *=-1; | ||
+ | if (ball.x > WIDTH-ball.r && ball.vx > 0) | ||
+ | ball.vx *=-1; | ||
+ | if (ball.y < ball.r && ball.vy < 0) | ||
+ | ball.vy *=-1; | ||
+ | if (ball.y > WIDTH-ball.r && ball.vy > 0) | ||
+ | ball.vy *=-1; | ||
+ | |||
+ | for (var j = i + 1; j < count; j++) { | ||
+ | var ball2= balls[j]; | ||
+ | var z = (ball.x - ball2.x) * (ball.getVx() - ball2.getVx()) + (ball.y - ball2.y) * (ball.getVy() - ball2.getVy()); | ||
+ | var l = Math.pow(ball.getVx() - ball2.getVx(), 2) + Math.pow(ball.getVy() - ball2.getVy(), 2); | ||
+ | var m = Math.pow(ball.x - ball2.x, 2) + Math.pow(ball.y - ball2.y, 2) - Math.pow(ball.r + ball2.r, 2); | ||
+ | |||
+ | var d = z*z - l*m; | ||
+ | |||
+ | var t0 = -(z + Math.sqrt(d)) / l; | ||
+ | |||
+ | var p = Math.pow(ball.x - ball2.x, 2) + Math.pow(ball.y - ball2.y, 2); | ||
+ | |||
+ | if (t0 >= 0 && t0 <= 1 || p < Math.pow(ball.r + ball2.r, 2)) { | ||
+ | ball.x += t0 * ball.getVx(); | ||
+ | ball.y += t0 * ball.getVy(); | ||
+ | ball2.x += t0 * ball2.getVx(); | ||
+ | ball2.y += t0 * ball2.getVy(); | ||
+ | |||
+ | var px = ball.x - ball2.x; | ||
+ | var py = ball.y - ball2.y; | ||
+ | |||
+ | var q = 2 * (px * (ball2.vx - ball.vx) + py * (ball2.vy - ball.vy)) | ||
+ | |||
+ | var dvx = q * px / (Math.pow(px, 2) + Math.pow(py,2)) * ball.m * ball2.m / (ball.m + ball2.m); | ||
+ | var dvy = q * py / (Math.pow(px, 2) + Math.pow(py,2)) * ball.m * ball2.m / (ball.m + ball2.m); | ||
+ | var k = 1.38 * Math.pow(10,-23); | ||
+ | |||
+ | ball.vx += dvx / ball.m; | ||
+ | ball.vy += dvy / ball.m; | ||
+ | ball2.vx -= dvx / ball2.m; | ||
+ | ball2.vy -= dvy / ball2.m; | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | ball.move(); | ||
+ | } | ||
+ | |||
+ | |||
+ | draw(); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | function draw() { | ||
+ | ctx.clearRect(0, 0, canvas.width, canvas.height); | ||
+ | |||
+ | var c = canvas.width / WIDTH; | ||
+ | |||
+ | for (var i = 0; i < count; i++) { | ||
+ | var ball= balls[i]; | ||
+ | ctx.beginPath(); | ||
+ | ctx.arc(ball.x * c, ball.y * c, ball.r * c, 0, 2 * Math.PI, false); | ||
+ | |||
+ | if (document.getElementById('color').checked) | ||
+ | ctx.fillStyle = ball.color; | ||
+ | else | ||
+ | ctx.fillStyle = 'blue'; | ||
+ | |||
+ | ctx.fill(); | ||
+ | |||
+ | |||
+ | |||
+ | } | ||
+ | drawPath(); | ||
+ | } | ||
+ | |||
+ | function start() { | ||
+ | balls[0]= new Ball( WIDTH/2 , WIDTH/2, 500, 0, 0,'red'); | ||
+ | for (var i = 1; i < count; i++) { | ||
+ | var r = random(MIN_RADIUS, MAX_RADIUS); | ||
+ | balls[i] = new Ball(random(r, WIDTH - r), random(r, WIDTH - r), r, random(-MAX_SPEED, MAX_SPEED), random(-MAX_SPEED, MAX_SPEED),'blue'); | ||
+ | |||
+ | } | ||
+ | |||
+ | canvas = document.getElementById('GG'); | ||
+ | ctx = canvas.getContext('2d'); | ||
+ | |||
+ | setInterval(move, 1); | ||
+ | } | ||
+ | |||
+ | function weight() { | ||
+ | |||
+ | var r = parseInt(document.getElementById('weight').value); | ||
+ | if (r > WIDTH / 2 || r < 50) | ||
+ | return; | ||
+ | |||
+ | var oldMass = balls[0].m; | ||
+ | balls[0].r = r; | ||
+ | balls[0].calculateMass(); | ||
+ | |||
+ | balls[0].vx *= Math.sqrt(oldMass / balls[0].m); | ||
+ | balls[0].vy *= Math.sqrt(oldMass / balls[0].m); | ||
+ | |||
+ | if (balls[0].x > WIDTH - r) | ||
+ | balls[0].x = WIDTH - r; | ||
+ | if (balls[0].x < r) | ||
+ | balls[0].x = r; | ||
+ | if (balls[0].y > WIDTH - r) | ||
+ | balls[0].y = WIDTH - r; | ||
+ | if (balls[0].y < r) | ||
+ | balls[0].y = r; | ||
+ | |||
+ | } | ||
+ | |||
+ | function changeSize() { | ||
+ | canvas.width = document.getElementById('size').value; | ||
+ | canvas.height = document.getElementById('size').value; | ||
+ | } | ||
+ | var tander = 0; | ||
+ | |||
+ | function drawPath() { | ||
+ | tander++; | ||
+ | if(tander === 5){ | ||
+ | tander=0; | ||
+ | if ( pathx.length>=1000){ | ||
+ | pathx.shift(); | ||
+ | pathy.shift(); | ||
+ | } | ||
+ | |||
+ | var c = canvas.width / WIDTH; | ||
+ | pathx.push( balls[0].x*c); | ||
+ | pathy.push( balls[0].y*c); | ||
+ | } | ||
+ | ctx.beginPath(); | ||
+ | ctx.lineWidth = 2; | ||
+ | ctx.strokeStyle = 'Black'; | ||
+ | ctx.moveTo(pathx[0], pathy[0]); | ||
+ | for (i=1;i<pathx.length; i++) | ||
+ | { | ||
+ | ctx.lineTo(pathx[i], pathy[i]); | ||
+ | } | ||
+ | |||
+ | ctx.stroke(); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | function add() { | ||
+ | var k = parseInt(document.getElementById('addCount').value); | ||
+ | k = Math.min(k , 250 - balls.length); | ||
+ | for (var i = 0; i < k; i++) { | ||
+ | var r = random(MIN_RADIUS, MAX_RADIUS); | ||
+ | balls[count + i] = new Ball(random(r, WIDTH - r), random(r, WIDTH - r), r, random(-MAX_SPEED, MAX_SPEED), random(-MAX_SPEED, MAX_SPEED)); | ||
+ | |||
+ | } | ||
+ | count += k; | ||
+ | } | ||
+ | |||
+ | function del() { | ||
+ | var k = Math.min(count - 1, parseInt(document.getElementById('addCount').value)); | ||
+ | balls = balls.slice(0, count - k); | ||
+ | count -= k; | ||
+ | } | ||
+ | |||
+ | function slowly() { | ||
+ | if (timeSpeed > -3) | ||
+ | timeSpeed--; | ||
+ | } | ||
+ | |||
+ | function faster() { | ||
+ | if (timeSpeed < 3) | ||
+ | timeSpeed++; | ||
+ | } | ||
+ | |||
+ | </script> | ||
+ | </body> | ||
+ | </html> |
Версия 14:44, 1 июня 2020
КОД
<!DOCTYPE html> <html lang="ru"> <head>
<title>Модель броуновского движения</title>
<meta charset="UTF-8">
</head>
<style> canvas { border: 1px solid black; } .pr {
border-bottom :1px solid #a2a9b1;
</style> <body onload = "start();" >
Модель Броуновского движения
Описание
Модель Броуновского движения с изоброжением траектории. Работа сделана на языке программирования JavaScript.
Исполнитель: Никита Натальин.
Группа:3630103/90001
Визуализация
<input type="text" id="size" value="500"> <input type="button" value="chaneg size" onclick="changeSize();">
<input type="text" id="addCount" value="10"> <input type="button" value="add" onclick="add();"> <input type="button" value="delete" onclick="del();">
<input type="text" id="weight" value="500"> <input type="button" value="weight" onclick="weight();">
<input type="button" value="slowly" onclick="slowly();"> <input type="button" value="faster" onclick="faster();">
<label><input type="checkbox" id="color" checked>color</label>
<canvas id="GG" width="500" height="500"></canvas> <script>
class Ball { constructor(x, y, r, vx, vy,color){ this.x = x; this.y = y; this.r = r; this.vx = vy; this.vy = vx;
this.calculateMass();
this.color = color; }
calculateMass() { this.m = (this.r * this.r * this.r)/50 ; }
getVx() { return this.vx * Math.pow(2, timeSpeed); }
getVy() { return this.vy * Math.pow(2, timeSpeed); }
move() { this.x += this.getVx(); this.y += this.getVy(); }
}
var count = 50;
var MAX_SPEED = 20; var MIN_RADIUS = 100; var MAX_RADIUS = 100; var WIDTH = 10000;
var timeSpeed = 0;
var balls = [];
var canvas; var ctx; var T = 300; var pathx = []; var pathy = [];
function random(min, max) { return Math.random() * (max - min) + min; }
function move() {
for (var i = 0; i < count; i++) { var ball = balls[i];
if (ball.x < ball.r && ball.vx < 0) ball.vx *=-1; if (ball.x > WIDTH-ball.r && ball.vx > 0) ball.vx *=-1; if (ball.y < ball.r && ball.vy < 0) ball.vy *=-1; if (ball.y > WIDTH-ball.r && ball.vy > 0) ball.vy *=-1;
for (var j = i + 1; j < count; j++) { var ball2= balls[j]; var z = (ball.x - ball2.x) * (ball.getVx() - ball2.getVx()) + (ball.y - ball2.y) * (ball.getVy() - ball2.getVy()); var l = Math.pow(ball.getVx() - ball2.getVx(), 2) + Math.pow(ball.getVy() - ball2.getVy(), 2); var m = Math.pow(ball.x - ball2.x, 2) + Math.pow(ball.y - ball2.y, 2) - Math.pow(ball.r + ball2.r, 2);
var d = z*z - l*m;
var t0 = -(z + Math.sqrt(d)) / l;
var p = Math.pow(ball.x - ball2.x, 2) + Math.pow(ball.y - ball2.y, 2);
if (t0 >= 0 && t0 <= 1 || p < Math.pow(ball.r + ball2.r, 2)) { ball.x += t0 * ball.getVx(); ball.y += t0 * ball.getVy(); ball2.x += t0 * ball2.getVx(); ball2.y += t0 * ball2.getVy();
var px = ball.x - ball2.x; var py = ball.y - ball2.y;
var q = 2 * (px * (ball2.vx - ball.vx) + py * (ball2.vy - ball.vy))
var dvx = q * px / (Math.pow(px, 2) + Math.pow(py,2)) * ball.m * ball2.m / (ball.m + ball2.m); var dvy = q * py / (Math.pow(px, 2) + Math.pow(py,2)) * ball.m * ball2.m / (ball.m + ball2.m); var k = 1.38 * Math.pow(10,-23);
ball.vx += dvx / ball.m; ball.vy += dvy / ball.m; ball2.vx -= dvx / ball2.m; ball2.vy -= dvy / ball2.m;
}
}
ball.move(); }
draw();
}
function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height);
var c = canvas.width / WIDTH;
for (var i = 0; i < count; i++) { var ball= balls[i]; ctx.beginPath(); ctx.arc(ball.x * c, ball.y * c, ball.r * c, 0, 2 * Math.PI, false);
if (document.getElementById('color').checked) ctx.fillStyle = ball.color; else ctx.fillStyle = 'blue';
ctx.fill();
} drawPath(); }
function start() { balls[0]= new Ball( WIDTH/2 , WIDTH/2, 500, 0, 0,'red'); for (var i = 1; i < count; i++) { var r = random(MIN_RADIUS, MAX_RADIUS); balls[i] = new Ball(random(r, WIDTH - r), random(r, WIDTH - r), r, random(-MAX_SPEED, MAX_SPEED), random(-MAX_SPEED, MAX_SPEED),'blue');
}
canvas = document.getElementById('GG'); ctx = canvas.getContext('2d');
setInterval(move, 1); }
function weight() {
var r = parseInt(document.getElementById('weight').value); if (r > WIDTH / 2 || r < 50) return;
var oldMass = balls[0].m; balls[0].r = r; balls[0].calculateMass();
balls[0].vx *= Math.sqrt(oldMass / balls[0].m); balls[0].vy *= Math.sqrt(oldMass / balls[0].m);
if (balls[0].x > WIDTH - r) balls[0].x = WIDTH - r; if (balls[0].x < r) balls[0].x = r; if (balls[0].y > WIDTH - r) balls[0].y = WIDTH - r; if (balls[0].y < r) balls[0].y = r;
}
function changeSize() { canvas.width = document.getElementById('size').value; canvas.height = document.getElementById('size').value; } var tander = 0;
function drawPath() { tander++; if(tander === 5){ tander=0; if ( pathx.length>=1000){ pathx.shift(); pathy.shift(); }
var c = canvas.width / WIDTH; pathx.push( balls[0].x*c); pathy.push( balls[0].y*c); } ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = 'Black';
ctx.moveTo(pathx[0], pathy[0]);
for (i=1;i<pathx.length; i++) { ctx.lineTo(pathx[i], pathy[i]); }
ctx.stroke(); }
function add() { var k = parseInt(document.getElementById('addCount').value); k = Math.min(k , 250 - balls.length); for (var i = 0; i < k; i++) { var r = random(MIN_RADIUS, MAX_RADIUS); balls[count + i] = new Ball(random(r, WIDTH - r), random(r, WIDTH - r), r, random(-MAX_SPEED, MAX_SPEED), random(-MAX_SPEED, MAX_SPEED));
} count += k; }
function del() { var k = Math.min(count - 1, parseInt(document.getElementById('addCount').value)); balls = balls.slice(0, count - k); count -= k; }
function slowly() { if (timeSpeed > -3) timeSpeed--; }
function faster() { if (timeSpeed < 3) timeSpeed++; }
</script> </body> </html>