Thursday, November 21, 2013

Orbital Mechanics

This past few weeks I've been working on a game in Computer Game Programming, Jerbal Space Program.

You design a space ship, and then you fly around in it, trying to land on the moon, or what have you. It's a pretty open sandbox game.

During it's development, I had to dive into orbital mechanics, to figure out the orbit of the spaceship, and then to render that orbit.

I though it was pretty neat, but it was hard to figure out from wikipedia, so I thought I'd write a post about it.

Lets dive into the function:

Ship.prototype.updateOrbit = function() {
    //Calculate orbit from orbital state vectors
    //Get the primary body the ship is orbiting
    var terr = entityManager.getTerrain(this.cx,this.cy);
    
    //One focus is in the center of the primary body 
    var focus = terr.center;
    var M = terr.mass;

    //Mu in the equations
    var mu = consts.G*(M+this.mass)
    
    //The posistion and velocity vectors.
    //Note that posistion is relative to the focus,
    //But the velocity is just the current velocity of the ship
    var r = util.vecMinus(this.center,focus)
    var v = [this.velX,this.velY];

    //Calculate the orbit specific energy, and from that we find the
    //semi-major axis. Note that this makes sense, as the semi major axis
    //basically tells us how high we'll go.
    var speed = this.getSpeed(); 
    var eng = (speed*speed)/2 - (mu/util.lengthOfVector(r));
    var a = -mu/(2*eng);
    
    //Calculate the eccentricity vector, and from that the eccentricity
    var tripleprod = util.tripleProduct(v,r,v);
    var vtimeshovermu = util.mulVecByScalar(1/mu,tripleprod); 
    var unitr = util.normalizeVector(r)
    var eccVec = util.vecMinus(vtimeshovermu,unitr);
    var ecc = util.lengthOfVector(eccVec);
    
    //ae is the distance from the center to a;
    var ae = a*ecc;
    //semi minor axis

    var b = a*Math.sqrt(1-ecc*ecc);
    //Find the center from the distance
    var cen = [f[0]-ae,f[1]];
    
    //Here we find the rotation of the eccentricity,
    //which tells us where the orbit is from the focus
    var angl = util.angleOfVector(eccVec);

    //rotate the center around the focus according to the angle
    cen = util.rotatePointAroundPoint(cen,angl,focus[0],focus[1]);

    //Set the properties of the orbit
    this.orbit = [cen[0], cen[1],a,b,angl,focus[0],focus[1]];
}

Now, using this we can plot our ellipse, knowing the center, and the angle of it. And it works, just zoom far enough out in the game, and take off! Happy flying!

2 comments: