A basic simulation & visualization for the three body problem.
<html>
<head>
<style>
#universe{
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<canvas id='universe'></canvas>
<script>
{
const canvas=document.getElementById("universe");
const ctx=canvas.getContext('2d');
const G=100;
const Mass=1;//kg
const Time=1;//s
const scale=1;//m
canvas.width=document.body.clientWidth;
canvas.height=document.body.clientHeight;
function sqrDis(a,b){
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
function Body(color){
this.color=color;
this.x=((Math.random()-0.5)*(canvas.width/3)+canvas.width/2)*scale;
this.y=((Math.random()-0.5)*(canvas.height/3)+canvas.height/2)*scale;
this.radius=2;
this.vx=Math.random()-0.5;
this.vy=Math.random()-0.5;
this.ax=this.ay=0;
this.drawnTo=(body)=>{
var dis2=sqrDis(this,body);
var dis=Math.sqrt(dis2);
var ex=(body.x-this.x)/dis,ey=(body.y-this.y)/dis;
var ac=G*Mass/dis2;
this.ax+=ac*ex,this.ay+=ac*ey;
};
this.move=()=>{//time set to 1
this.x+=this.vx*Time+this.ax*Time*Time/2;
this.y+=this.vy*Time+this.ay*Time*Time/2;
this.vx+=this.ax*Time;
this.vy+=this.ay*Time;
this.ax=this.ay=0;/*
if (this.y > canvas.height || this.y < 0) {
this.vy = -this.vy;
}
if (this.x > canvas.width || this.x < 0) {
this.vx = -this.vx;
}*/
};
this.draw=()=>{
ctx.beginPath();
ctx.arc(this.x/scale, this.y/scale, this.radius, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = this.color;
ctx.fill();
}
}
const objs=[new Body('blue'),new Body('red'),new Body('green')];
objs[2].vx=-objs[0].vx-objs[1].vx;
objs[2].vy=-objs[0].vy-objs[1].vy;
function getEp(){
var ans=0;
objs.forEach((i)=>{
objs.forEach((j)=>{
if(i!==j){
ans+=G/Math.sqrt(sqrDis(i,j));
}
});
});
return -ans*Mass/2;
}
function getEk(){
var ans=0;
objs.forEach((i)=>{
ans+=i.vx*i.vx+i.vy*i.vy;
});
return ans*Mass/2;
}
var E=getEp()+getEk();
function update(){
ctx.fillStyle = 'rgba(255, 255, 255, 0.01)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
objs.forEach((i)=>{
objs.forEach((j)=>{
if(i!==j){
i.drawnTo(j);
}
});
});
objs.forEach((i)=>{
i.move(),i.draw();
});
objs[2].vx=-objs[0].vx-objs[1].vx;
objs[2].vy=-objs[0].vy-objs[1].vy;
var k=Math.sqrt((E-getEp())/getEk());
objs.forEach((i)=>{
i.vx*=k;
i.vy*=k;
});
window.requestAnimationFrame(update);
}
update();
}
</script>
</body>
</html>