Skip to content

Instantly share code, notes, and snippets.

@SavinaRoja
Created March 16, 2012 21:10
Show Gist options
  • Save SavinaRoja/2052724 to your computer and use it in GitHub Desktop.
Save SavinaRoja/2052724 to your computer and use it in GitHub Desktop.
A non-deterministic simulation of gravity using HTML5's canvas.
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
//I'd like to credit Eric Rowell at http://www.html5canvastutorials.com/ for eir instruction
window.requestAnimFrame = (function(callback){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60)
}
})()
function drawBody(myBody){
var canvas = document.getElementById("myCanvas")
var context = canvas.getContext("2d")
context.beginPath()
context.arc(myBody.x, myBody.y, myBody.radius, 0, 2 * Math.PI, false)
context.fillStyle = myBody.color
context.fill()
context.lineWidth = myBody.borderWidth
context.strokeStyle = "black"
context.stroke()
}
function animate(lastTime, planet, moon){
var canvas = document.getElementById("myCanvas")
var context = canvas.getContext("2d")
//update variables
var date = new Date()
var time = date.getTime()
var timeDiff = time - lastTime
var gConstant = 0.2 // The Gravitational Constant
var distance = Math.sqrt(Math.pow(planet.x - moon.x, 2) + Math.pow(planet.y - moon.y, 2))
var force = gConstant * planet.m * moon.m / Math.pow(distance, 2)
//I am working with a weird mix of cartesian and polar coordinates
//These are the angles from one body to another
var toPlanet = Math.atan2(planet.y - moon.y, planet.x - moon.x) //From the moon to the planet
var toMoon = toPlanet - Math.PI
// Apply acceleration to velocities
planet.vx = planet.vx + ((force / planet.m) * Math.cos(toMoon))
planet.vy = planet.vy + ((force / planet.m) * Math.sin(toMoon))
moon.vx = moon.vx + ((force / moon.m) * Math.cos(toPlanet))
moon.vy = moon.vy + ((force / moon.m) * Math.sin(toPlanet))
//Apply velocities to positions
planet.x += (planet.vx * timeDiff)
planet.y += (planet.vy * timeDiff)
moon.x += (moon.vx * timeDiff)
moon.y += (moon.vy * timeDiff)
//Update most recent time
lastTime = time
//clear
context.clearRect(0, 0, canvas.width, canvas.height)
//draw
drawBody(planet)
drawBody(moon)
// request new frame
requestAnimFrame(function(){
animate(lastTime, planet, moon)
})
}
window.onload = function(){
var canvas = document.getElementById("myCanvas")
var context = canvas.getContext("2d")
var pMass = 1000
var mMass = 200
var massR = mMass / pMass
var xVelInit = 0.05
var yVelInit = 0.2
var planet = {
m: pMass,
x: (canvas.width / 2),
y: (canvas.height / 2),
vx: -1 * xVelInit * massR,
vy: -1 * yVelInit * massR,
radius: 50,
borderWidth: 4,
color: "blue"
}
var moon = {
m: mMass,
x: (canvas.width * 3 / 4),
y: (canvas.height / 2),
vx: xVelInit,
vy: yVelInit,
radius: 20,
borderWidth: 4,
color: "grey"
}
drawBody(planet)
drawBody(moon)
//wait a second before letting them orbit
setTimeout(function(){
var date= new Date()
var time = date.getTime()
animate(time, planet, moon)
}, 1000)
}
</script>
</head>
<body>
<canvas id="myCanvas" width="600" height="600"></canvas>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment