Участник:StarfloFr — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
м
м
Строка 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>