Skip to content

Instantly share code, notes, and snippets.

@ElemarJR
Created October 16, 2011 01:30
Show Gist options
  • Save ElemarJR/1290398 to your computer and use it in GitHub Desktop.
Save ElemarJR/1290398 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Spheres</title>
<style type="text/css">
*
{
margin: 0;
padding: 0;
}
html, body
{
height: 100%;
width: 100%;
}
canvas
{
display: block;
}
#target
{
background: #001022;
}
</style>
</head>
<body>
<canvas id="target" width="500" height="500">
</canvas>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
var canvas = $("#target");
var context = canvas.get(0).getContext("2d");
var canvasWidth = canvas.width();
var canvasHeight = canvas.height();
$(window).resize(resizeCanvas);
function resizeCanvas() {
canvas.attr("width", $(window).get(0).innerWidth);
canvas.attr("height", $(window).get(0).innerHeight);
canvasWidth = canvas.width();
canvasHeight = canvas.height();
};
var Sphere = function (x, y, radius, mass, vX, vY) {
this.x = x;
this.y = y;
this.radius = radius;
this.mass = mass;
this.vX = vX;
this.vY = vY;
this.updatePosition = function () {
this.x += this.vX;
this.y += this.vY;
};
this.checkBoundaryCollision = function () {
if (this.x - this.radius < 0) {
this.x = this.radius;
this.vX *= -1;
} else if (this.x + this.radius > canvasWidth) {
this.x = canvasWidth - this.radius;
this.vX *= -1;
}
if (this.y - this.radius < 0) {
this.y = this.radius;
this.vY *= -1;
} else if (this.y + this.radius > canvasHeight) {
this.y = canvasHeight - this.radius;
this.vY *= -1;
}
}
}
resizeCanvas();
var spheresLength = 20;
var spheres = new Array();
function loadContent() {
for (var i = 0; i < spheresLength; i++) {
var x = 20 + (Math.random() * (canvasWidth - 40));
var y = 20 + (Math.random() * (canvasHeight - 40));
var radius = 5 + Math.random() * 10;
var mass = radius / 2;
var vX = Math.random() * 4 - 2;
var vY = Math.random() * 4 - 2;
spheres.push(new Sphere(x, y, radius, mass, vX, vY));
};
animate();
}
loadContent();
function animate() {
update();
draw();
setTimeout(animate, 33);
}
function update() {
for (var i = 0; i < spheresLength; i++) {
var sphere1 = spheres[i];
for (var j = i + 1; j < spheresLength; j++) {
var sphere2 = spheres[j];
var dX = sphere2.x - sphere1.x;
var dY = sphere2.y - sphere1.y;
var distance = Math.sqrt((dX * dX) + (dY * dY));
if (distance < sphere1.radius + sphere2.radius) {
var angle = Math.atan2(dY, dX);
var sine = Math.sin(angle);
var cosine = Math.cos(angle);
var x = 0;
var y = 0;
var xB = dX * cosine + dY * sine;
var yB = dY * cosine - dX * sine;
var vX = sphere1.vX * cosine + sphere1.vY * sine;
var vY = sphere1.vY * cosine - sphere1.vX * sine;
var vXb = sphere2.vX * cosine + sphere2.vY * sine;
var vYb = sphere2.vY * cosine - sphere2.vX * sine;
var vTotal = vX - vXb;
vX = (
(sphere1.mass - sphere2.mass) * vX + 2 * sphere2.mass * vXb
)
/ (sphere1.mass + sphere2.mass);
vXb = vTotal + vX;
xB = x + (sphere1.radius + sphere2.radius);
sphere1.x = sphere1.x + (x * cosine - y * sine);
sphere1.y = sphere1.y + (y * cosine + x * sine);
sphere2.x = sphere1.x + (xB * cosine - yB * sine);
sphere2.y = sphere1.y + (yB * cosine + xB * sine);
sphere1.vX = vX * cosine - vY * sine;
sphere1.vY = vY * cosine + vX * sine;
sphere2.vX = vXb * cosine - vYb * sine;
sphere2.vY = vYb * cosine + vXb * sine;
}
}
sphere1.updatePosition();
sphere1.checkBoundaryCollision();
}
}
function draw() {
context.clearRect(0, 0, canvasWidth, canvasHeight);
context.fillStyle = "rgb(255, 255, 255)";
for (var i = 0; i < spheresLength; i++) {
var sphere = spheres[i];
context.beginPath();
context.arc(sphere.x, sphere.y, sphere.radius, 0, Math.PI * 2);
context.closePath();
context.fill();
}
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment