7

I'm trying to solve Kepler's Equation as a step towards finding the true anomaly of an orbiting body given time. It turns out though, that Kepler's equation is difficult to solve, and the wikipedia page describes the process using calculus. Well, I don't know calculus, but I understand that solving the equation involves an infinite number of sets which produce closer and closer approximations to the correct answer.

I can't see from looking at the math how to do this computationally, so I was hoping someone with a better maths background could help me out. How can I solve this beast computationally?

FWIW, I'm using F# -- and I can calculate the other elements necessary for this equation, it's just this part I'm having trouble with.

I'm also open to methods which approximate the true anomaly given time, periapsis distance, and eccentricity

Carson Myers
  • 37,678
  • 39
  • 126
  • 176
  • interesting but i don't use F# if with java then i could help but still learning it. – S L Mar 13 '11 at 06:08
  • @experimentX I added a language-agnostic tag. I don't mind converting from pseudo-code or another language. – Carson Myers Mar 13 '11 at 06:09
  • Well, it seems that kepler's equation is quite different than the elleptical equation i studied. still, have to work .. it may take a lot of time. – S L Mar 13 '11 at 06:19
  • some related QA's: [Solving Kepler's Equation](http://stackoverflow.com/a/25403425/2521214) , [C++ implementation](http://stackoverflow.com/a/25722336/2521214) , [realistic n-body solar system simulation](http://stackoverflow.com/a/28020934/2521214) – Spektre Oct 06 '15 at 08:29

3 Answers3

9

This paper:

A Practical Method for Solving the Kepler Equation
http://murison.alpheratz.net/dynamics/twobody/KeplerIterations_summary.pdf

shows how to solve Kepler's equation using an iterative computing method. It should be fairly straightforward to translate it to the language of your choice.


You might also find this interesting. It's an ocaml program, part of which claims to contain a Kepler Equation solver. Since F# is in the ML family of languages (as is ocaml), this might provide a good starting point.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
3

wanted to drop a reply in here in case this page gets found by anyone else looking for similar materials.

The following was written as an "expression" in Adobe's After Effects software, so it's javascriptish, although I have a Python version for a different app (cinema 4d). The idea is the same: execute Newton's method iteratively until some arbitrary precision is reached.

Please note that I'm not posting this code as exemplary or meaningfully efficient in any way, just posting code we produced on a deadline to accomplish a specific task (namely, move a planet around a focus according to Kepler's laws, and do so accurately). We don't write code for a living, and so we're also not posting this for critique. Quick & dirty is what meets deadlines.

In After Effects, any "expression" code is executed once - for every single frame in the animation. This restricts what one can do when implementing many algorithms, due to the inability to address global data easily (other algorithms for Keplerian motion use interatively updated velocity vectors, an approach we couldn't use). The result the code leaves behind is the [x,y] position of the object at that instant in time (internally, this is the frame number), and the code is intended to be attached to the position element of an object layer on the timeline.

This code evolved out of material found at http://www.jgiesen.de/kepler/kepler.html, and is offered here for the next guy.

pi = Math.PI;
function EccAnom(ec,am,dp,_maxiter) { 
// ec=eccentricity, am=mean anomaly,
// dp=number of decimal places
    pi=Math.PI;
    i=0; 
    delta=Math.pow(10,-dp); 
    var E, F; 

    // some attempt to optimize prediction
    if (ec<0.8) {
        E=am;
    } else {
       E= am + Math.sin(am);
    }
    F = E - ec*Math.sin(E) - am; 
    while ((Math.abs(F)>delta) && (i<_maxiter)) {
        E = E - F/(1.0-(ec* Math.cos(E) )); 
        F = E - ec * Math.sin(E) - am; 
        i = i + 1;
    } 
    return Math.round(E*Math.pow(10,dp))/Math.pow(10,dp);
} 
function TrueAnom(ec,E,dp) { 
    S=Math.sin(E); 
    C=Math.cos(E); 
    fak=Math.sqrt(1.0-ec^2);

    phi = 2.0 * Math.atan(Math.sqrt((1.0+ec)/(1.0-ec))*Math.tan(E/2.0));
    return Math.round(phi*Math.pow(10,dp))/Math.pow(10,dp);
} 
function MeanAnom(time,_period) {
    curr_frame  = timeToFrames(time);
    if (curr_frame <= _period) {
        frames_done = curr_frame;
        if (frames_done < 1) frames_done = 1;
    } else {
        frames_done = curr_frame % _period;
    }
    _fractime = (frames_done * 1.0 ) / _period;
    mean_temp   = (2.0*Math.PI) * (-1.0 * _fractime);
    return mean_temp;
}
//==============================
// a=semimajor axis, ec=eccentricity, E=eccentric anomaly 
// delta = delta digits to exit, period = per., in frames
//----------------------------------------------------------
_eccen      = 0.9;              
_delta      = 14;
_maxiter    = 1000;                 
_period     = 300;          
_semi_a     = 70.0;
_semi_b     = _semi_a * Math.sqrt(1.0-_eccen^2); 
_meananom = MeanAnom(time,_period);
_eccentricanomaly = EccAnom(_eccen,_meananom,_delta,_maxiter);
_trueanomaly = TrueAnom(_eccen,_eccentricanomaly,_delta);
r = _semi_a * (1.0 - _eccen^2) / (1.0 + (_eccen*Math.cos(_trueanomaly)));
x = r * Math.cos(_trueanomaly);
y = r * Math.sin(_trueanomaly);
_foc=_semi_a*_eccen;
[1460+x+_foc,540+y];
j0k
  • 22,600
  • 28
  • 79
  • 90
2

You could check this out, implemented in C# by Carl Johansen

Represents a body in elliptical orbit about a massive central body

Here is a comment from the code

True Anomaly in this context is the angle between the body and the sun. For elliptical orbits, it's a bit tricky. The percentage of the period completed is still a key input, but we also need to apply Kepler's equation (based on the eccentricity) to ensure that we sweep out equal areas in equal times. This equation is transcendental (ie can't be solved algebraically) so we either have to use an approximating equation or solve by a numeric method. My implementation uses Newton-Raphson iteration to get an excellent approximate answer (usually in 2 or 3 iterations).

Nightfirecat
  • 11,432
  • 6
  • 35
  • 51
Aivan Monceller
  • 4,636
  • 10
  • 42
  • 69