Skip to content

Commit

Permalink
Revert "Revert "Add 1-Gravity.html""
Browse files Browse the repository at this point in the history
This reverts commit d5e4bbb.
  • Loading branch information
sphamba committed Nov 13, 2016
1 parent d5e4bbb commit 0f92300
Show file tree
Hide file tree
Showing 3 changed files with 545 additions and 1 deletion.
296 changes: 296 additions & 0 deletions Coding-the-Universe/01-Gravitation/1-Gravity.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
<html>
<head>
<title>Gravity</title>

<style>

canvas {
display: block;
}

html, body {
margin: 0px;
}

</style>
</head>

<body>
<canvas id="game"></canvas>


<script>

var canvas = document.getElementById("game");

var context = canvas.getContext("2d"),
width = window.innerWidth,
height = window.innerHeight,
ratio = window.devicePixelRatio;

canvas.width = width * ratio;
canvas.height = height * ratio;
canvas.style.width = width + "px";
canvas.style.height = height + "px";
var zoom = 1, camx = 0, camy = 0;
context.scale(ratio*zoom, ratio*zoom);
context.strokeStyle = "red";

var pause = false, showForce = false;
var dt = 1;

addEventListener("keydown", function(event) {
var code = event.keyCode;

switch (code)
{
case 38:
zoom += 0.1;
break;

case 40:
zoom -= 0.1;
break;

case 39:
dt += 0.1;
break;

case 37:
dt -= 0.1;
break;

case 87:
camy -= 10;
break;

case 83:
camy += 10;
break;

case 65:
camx -= 10;
break;

case 68:
camx += 10;
break;

case 82:
planets.length = 0;
generate();
break;

case 67: {

var ax = 0, ay = 0, totalMass = 0, previousMass = planets[0].mass;

for (var i = 0; i < planets.length; i++)
{
var p = planets[i];

ax += p.x * p.mass;
ay += p.y * p.mass;
previousMass = p.mass;
totalMass += p.mass;
}

camx = ax / totalMass - width / 2 / zoom;
camy = ay / totalMass - height / 2 / zoom;
} break;

case 77: {

var index = 0, previousMass = 0;

for (var i = 0; i < planets.length; i++)
{
if (planets[i].mass > previousMass)
{
index = i;
previousMass = planets[i].mass;
}
}
camx = planets[index].x - width / 2 / zoom;
camy = planets[index].y - height / 2 / zoom;
} break;

case 80:
pause = !pause;
break;

case 70:
showForce = !showForce;
break;
}
});

addEventListener("mousedown", function(event) {
var x = event.clientX / zoom + camx, y = event.clientY / zoom + camy;

var p = new Planet(0);
p.x = x;
p.y = y;
p.mass = parseFloat(prompt("What's the mass of the new planet ?", 500));
p.dx = parseFloat(prompt("What's the initial x speed ?", 0));
p.dy = parseFloat(prompt("What's the initial y speed ?", 0));
p.radius = Math.sqrt(p.mass);

planets.push(p);
});

var planets = [];

generate();
animate();

function Planet(maxMass, dx, dy)
{
this.x = Math.random() * width;
this.y = Math.random() * height;
this.dx = Math.random() * dx;
this.dy = Math.random() * dy;
this.mass = Math.random() * maxMass;
this.radius = Math.sqrt(this.mass);
this.criticalDistance = this.radius * Math.sqrt(2);
this.type = "Brown dwarf";

this.update = function()
{
for (var i = 0; i < planets.length; i++)
{
var p = planets[i];

var dx = p.x - this.x, dy = p.y - this.y;
var dist = dx * dx + dy * dy;

if (dist != 0)
{
var distance = Math.sqrt(dist);

if (distance < (this.radius + p.radius))
{
if (p.mass < this.mass)
{
this.mass += p.mass;
this.x = (this.x * this.mass + p.x * p.mass) / (this.mass + p.mass);
this.y = (this.y * this.mass + p.y * p.mass) / (this.mass + p.mass);
this.dx = (this.mass * this.dx + p.mass * p.dx) / (this.mass + p.mass) * dt;
this.dy = (this.mass * this.dy + p.mass * p.dy) / (this.mass + p.mass) * dt;
planets.splice(i, 1);
i--;
this.radius = Math.sqrt(this.mass);
}
}
else
{
var force = p.mass / dist;

var angle = Math.atan2(p.y - this.y, p.x - this.x);
var dirx = force * Math.cos(angle), diry = force * Math.sin(angle);

this.dx += dirx;
this.dy += diry;
}
}
}

this.x += this.dx * dt;
this.y += this.dy * dt;


if (this.mass > 8000)
{
this.type = "Yellow dwarf";
}
else if (this.mass > 2800) // 1400*2
{
this.type = "Red dwarf";
}
};
}


function generate()
{
var count = Math.random() * parseInt(prompt("How many particles ?", 3000)), mass = parseInt(prompt("What is the maximum mass ?", 100)), movx = parseFloat(prompt("Enter initial x movement : ", 0)), movy = parseFloat(prompt("Enter initial y movement : ", 0));

for (var i = 0; i < count; i++)
{
planets.push(new Planet(mass, movx, movy));
}
}

function animate()
{
draw();

if (!pause)
update();

requestAnimationFrame(animate);
}

function draw()
{
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, width, height);
context.fillStyle = "white";
context.fillText("Camera position : " + camx + " ; " + camy + "\nCamera zoom : x" + zoom + "\nParticles count : " + planets.length + "\n Simulation speed : " + dt, 0, 40);
context.fillText("Last Object's position : " + planets[0].x + " ; " + planets[0].y, 0, 80);
context.save();

context.fillStyle = "#000";
context.fillRect(0, 0, width, height);

context.scale(ratio*zoom, ratio*zoom);
context.translate(-camx, -camy);

for (var i = 0; i < planets.length; i++)
{
var p = planets[i];

context.beginPath();
context.arc(p.x, p.y, p.radius, 0, 2*Math.PI);

if (p.type == "Brown dwarf")
{
context.fillStyle = "rgb(130, 100, 100)";
}
else if (p.type == "Red dwarf")
{
context.fillStyle = "rgb(200, 70, 70)";
}
else if (p.type == "Yellow dwarf")
{
context.fillStyle = "rgb(220, 220, 0)";
}

context.fill();

if (showForce)
{
context.beginPath();
context.moveTo(p.x, p.y);
context.lineTo(p.x + p.dx * 10, p.y + p.dy * 10);
context.arc(p.x, p.y, p.criticalDistance, 0, 2*Math.PI);
context.stroke();
}
}

context.restore();
}

function update()
{
for (var i = 0; i < planets.length; i++)
{
var p = planets[i];

p.update();
}
}

</script>
</body>
</html>
Loading

0 comments on commit 0f92300

Please sign in to comment.