I have asked a question similar to this before but have not been able to find an answer so im going to provide a bit more detail and hope that someone knows what im talking about.

I have a series of functions which use keplers laws to compute where an object will be at "t" time in 2D space while orbiting a celestial body of some kind. This is a crude solution to the 2 body problem which i intend to use in a 2D physics-based space game. Here is my code so far:

float KeplersEquation(float meanAnomaly, float eccentricAnomaly, float eccentricity)
{
    return eccentricAnomaly - (eccentricity * Mathf.Sin(eccentricAnomaly)) - meanAnomaly;
}

float KeplersEquation_Differentiated(float eccentricAnomaly, float eccentricity)
{
    return 1 - (eccentricity * Mathf.Cos(eccentricAnomaly));
}

float SolveKepler(float meanAnomaly, float eccentricity)
{
    float accuracy = 0.000001f;
    int maxIterations = 100;

    float eccentricAnomaly = eccentricity > 0.8f ? Mathf.PI : meanAnomaly;

    for (int i = 0; i < maxIterations; i++)
    {
        float nextValue = eccentricAnomaly - (KeplersEquation(meanAnomaly, eccentricAnomaly, eccentricity)) / KeplersEquation_Differentiated(eccentricAnomaly, eccentricity);
        float difference = Mathf.Abs(eccentricAnomaly - nextValue);
        eccentricAnomaly = nextValue;

        if (difference < accuracy) break;
    }

    return eccentricAnomaly;
}

/// <summary> Calculates a position on the orbit for a given value of t ranging between 0 and 1 </summary>
public Vector2 CalculatePointOnOrbit(float apoapsis, float periapsis, float argumentOfPeriapsis, float t)
{
    float semiMajorAxis = (apoapsis + periapsis) / 2f;
    float semiMinorAxis = Mathf.Sqrt(apoapsis * periapsis);

    float meanAnomaly = t * Mathf.PI * 2f; // Mean anomaly ranges anywhere from 0 - 2π
    float linearEccentricity = semiMajorAxis - periapsis;
    float eccentricity = linearEccentricity / semiMajorAxis; // Eccentricity ranges from 0 - 1 with values tending to 1 being increasingly elliptical

    float eccentricAnomaly = SolveKepler(meanAnomaly, eccentricity);

    float x = semiMajorAxis * (Mathf.Cos(eccentricAnomaly) - eccentricity);
    float y = semiMinorAxis * Mathf.Sin(eccentricAnomaly);

    Quaternion parametricAngle = Quaternion.AngleAxis(argumentOfPeriapsis, Vector2.up);
    return parametricAngle * new Vector2(x, y);
}

Since this is a physics based game, id love to be able to take the current position and velocity of an orbiting object, as well as the gravitational parameter of an attracting object and translate them into either keplerian elements or the simplified versions used within my function (apoapsis, periapsis, argument of periapsis and time), this would allow me to dynamically change the orbit of an object whenever it collides with something or an external force is applied. I have read up how to do this in 3D space, but I am struggling to grasp the concept of it and therefore cant figure out how to do it in 2D. If someone could explain how to go about this in 2D as well as any other tips you may have that would be very much appreciated.

1

There are 1 best solutions below

0
James Tursa On

2D calculations are the same as 3D calculations except you are going to have 0's in the z spots. For discussions and algorithms of this you can see here:

https://space.stackexchange.com/questions/19322/converting-orbital-elements-to-cartesian-state-vectors

which points you to here:

https://ccar.colorado.edu/asen5070/handouts/cart2kep2002.pdf

You will just have to adjust things for the planar case to get a single answer for RAAN + ArgLat. E.g., since hx and hy are both 0 for the planar case, you can't do the RAAN = atan2(hx,-hy) calculation as written. So you could just arbitrarily assign it a constant value of 0 for your case. Etc.