/ Published in: JavaScript
It's gravity
Expand |
Embed | Plain Text
<!doctype html> <HTML> <head> <title>Gravity!</title> <style type = "text/css"> h1{ color:rgb(255,255,255); } body{ background-color:rgb(0,0,0); } plot_surf{ background-color:rgb(0,0,0); } </style> <script type = "text/javascript"> /* @James Siene - September 28, 2010 - This program simulates what gravity might look like on some particles in space. The gravity has been intensified to scale with the programs display settings - its made to look nice and its NOT 100% accurate with real gravity, its an approximation */ // For drawing to the Canvas object var canvas; var ctx; var imgLight; // The universal constants var kNumPlanets = 10; var kMaxMass = 1000; var kSolarMass = 30000; var kGravity = 0.05; var kFps = 50; var kGenesisVelocity = 20.0; var kTimestep = .5; var kUniverseDepth; var camera function Vector (nx, ny, nz) { this.x = nx; this.y = ny; this.z = nz; this.magnitude = function(){ return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); } this.add = function(rhs){ return new Vector(this.x + rhs.x, this.y + rhs.y, this.z + rhs.z); } this.sub = function(rhs){ return new Vector(this.x - rhs.x, this.y - rhs.y, this.z - rhs.z); } this.div = function(num){ return new Vector(this.x / num, this.y / num, this.z / num); } this.mul = function(num){ return new Vector(this.x * num, this.y * num, this.z * num); } this.distance = function(rhs){ return Math.sqrt((rhs.x - this.x)^2 + (rhs.y - this.y)^2); } } function Planet(newMass, isSolarObject) { this.pos = new Vector(0, 0, 0); this.vel = new Vector(0, 0, 0); this.acc = new Vector(0, 0, 0); this.mass = newMass; this.isSolar = isSolarObject; this.draw = function(){ var size = Math.sqrt(this.mass) * (this.pos.z / camera.z); if (size < 2) size = 2; // double size to (since it's a radius, and we need a diameter) var halfSize = size; size *= 2; ctx.drawImage(imgLight, this.pos.x - halfSize, this.pos.y - halfSize, size, size); } this.updateVelocity = function(){ this.vel = this.vel.add(this.acc); } this.updatePosition = function() { this.pos = this.pos.add(this.vel); } this.updateAcceleration = function(otherPlanet) { var posDiff = otherPlanet.pos.sub(this.pos); var tDiff = Math.sqrt(posDiff.x * posDiff.x + posDiff.y * posDiff.y + posDiff.z * posDiff.z); var force = kGravity * (otherPlanet.mass) / (tDiff * tDiff); return new Vector(posDiff.x * force, posDiff.y * force, posDiff.z * force); } } var planets = new Array(); function init(){ //Create canvas object canvas = document.getElementById("plot_surf"); ctx = canvas.getContext("2d"); imgLight = new Image(); imgLight.src = "images/light.png"; kUniverseDepth = Math.sqrt(canvas.width * canvas.height); camera = new Vector(canvas.width / 2, canvas.height / 2, kUniverseDepth); // Center Planet (Solar Object) planets[0] = new Planet(kSolarMass, true); planets[0].pos = new Vector(canvas.width / 2, canvas.height / 2, kUniverseDepth / 2); for (var curPlanet = 1; curPlanet < kNumPlanets; curPlanet++){ planets[curPlanet] = new Planet((kMaxMass / 4) + Math.floor(Math.random() * (kMaxMass * 0.75)),false); planets[curPlanet].pos.x = Math.floor(Math.cos((curPlanet / kNumPlanets) * Math.PI * 2) * (canvas.width / 2)) + canvas.width / 2; planets[curPlanet].pos.y = Math.floor(Math.sin((curPlanet / kNumPlanets) * Math.PI * 2) * (canvas.height / 2)) + canvas.height / 2; planets[curPlanet].pos.z = Math.floor(Math.random() * kUniverseDepth); // Genesis velocity application planets[curPlanet].vel = new Vector( Math.floor(Math.random() * kGenesisVelocity) - (kGenesisVelocity / 2), Math.floor(Math.random() * kGenesisVelocity) - (kGenesisVelocity / 2), Math.floor(Math.random() * kGenesisVelocity) - (kGenesisVelocity / 2)); } setInterval(doPhysics, 1000 / kFps); } function doPhysics(){ ctx.fillStyle="rgba(0,32,64,0.15)"; ctx.fillRect(0, 0, canvas.width, canvas.height); var relocVector = new Vector(0, 0, 0); // First we'll update all of the planets accelerations for (var curPlanet in planets){ var newAccel = new Vector(0, 0, 0); for (var otherPlanet in planets){ if (curPlanet == otherPlanet) continue; newAccel = newAccel.add(planets[curPlanet].updateAcceleration(planets[otherPlanet])); } planets[curPlanet].acc = newAccel.div(kNumPlanets - 1); planets[curPlanet].updateVelocity(); } // Update all positions and get the offset of the solar object for (var curPlanet in planets){ planets[curPlanet].updatePosition(); if (planets[curPlanet].isSolar){ relocVector = new Vector( planets[curPlanet].pos.x - (canvas.width / 2), planets[curPlanet].pos.y - (canvas.height / 2), planets[curPlanet].pos.z - (kUniverseDepth / 2)); } } relocVector = relocVector.div(8); planets.sort( function(a, b) { return a.pos.z - b.pos.z; }); for (var curPlanet in planets){ // Move planets to center the solar object planets[curPlanet].pos = planets[curPlanet].pos.sub(relocVector); planets[curPlanet].draw(); } } </script> </head> <BODY onload="init();"> <h1>Gravitational Model</h1> <canvas id="plot_surf" width=800 height=600></canvas> </BODY> </HTML>
You need to login to post a comment.
