PlanetSim

by Santiago J

HTML

<div id="wrapper">
    <button id="init" onclick="init()">Initialize</button>
    <button id="run">Run</button>
    <button id="stop">Stop</button>
    <div id="stage"></div>
    <pre id="dump"></pre>
    <p id="debug"></p>
</div>

CSS

html, body {
    background-color: #222;
    color: #eee;
    margin: 0;
    padding: 0;
}
#wrapper {
    text-align: center;
}
#stage {
    margin: 1em 0;
}
#stage canvas {
    outline: 1px solid #777;
}

JavaScript

function System(el, W, H) {
    var canvas = document.createElement("canvas");
    this.stage = el;
    this.canvas = canvas;
    this.canvas.width = typeof W === "number" ? W : 400;
    this.canvas.height = typeof H === "number" ? H : 300;
    this.ctx = canvas.getContext("2d");
    this.ctx.fillStyle = "cyan";
    this.bodies = [];
    this.dt = 0.03125;
    this.intervalId = 0;
    this.stage.appendChild(this.canvas);
}

System.prototype.render = function() {
    var i = this.bodies.length,
        ctx = this.ctx,
        b;

    ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    while (i--) {
        b = this.bodies[i];
        ctx.beginPath();
        ctx.arc(b.x, b.y, b.r, 0, 6.2432, false);
        ctx.fill();
    }
};

System.prototype.updateAccelerations = function() {
    var i = this.bodies.length,
        j = i,
        a, b, dx, dy, _temp, r;

    while (j--) {
        a = this.bodies[j];
        a.ax = a.ay = 0;
    }

    while (i--) {
        a = this.bodies[i];
        if (i < 1) break;
        j = i;
        while (j--) {
            b = this.bodies[j];
            dx = a.x - b.x;
            dy = a.y - b.y;
            _temp = dx * dx + dy * dy;
            if (_temp < 9) continue;
            r = Math.sqrt(_temp);
            dx /= r;
            dy /= r;

            _temp = 50000 * a.m / _temp;
            b.ax = dx * _temp;
            b.ay = dy * _temp;
            _temp *= -b.m / a.m;
            a.ax = dx * _temp;
            a.ay = dy * _temp;
        }
    }
};

System.prototype.Body = function(m, x, y, oldX, oldY) {
    this.m = typeof m === "number" && m > 0 ? m : 1;
    this.r = Math.pow(this.m, 1 / 3) * 10 | 0;
    this.x = typeof x === "number" ? x : 0;
    this.y = typeof y === "number" ? y : 0;
    this.$x = typeof oldX === "number" ? oldX : this.x;
    this.$y = typeof oldY === "number" ? oldY : this.y;
    this.ax = this.ay = 0;
};

System.prototype.addBody = function(m, x, y, oldX, oldY) {
   ...