Elliptical orbits are hard
This page contains math formulas. If it doesn't load, reload the page
Elliptical orbits
My game, i’m working on, uses circular orbits. They are really easy to compute and maintain. But they, well… circular. I want to add stretched orbits for some objects. So i made a little research about how they works. By now i only need time function, so in this article i will present equations and code required to achive it.
Elliptical orbit is an orbit with eccentricity in range 0-1. Elliptical orbits also include circular orbits (eccentricity = 0).
The problem with elliptical orbits, is ecentricity. Eccentricity determines how much orbit deviates from circular orbit. 0 for circular, 1 for parabolic trajectory and >1 for hyperbolic trajectory.
Elliptical can’t been described with \(\displaystyle{ \frac {x^{2}}{a^{2}}}+{\frac {y^{2}}{b^{2}}}=1\) like ellipse - gravity is not linear and affects velocity differently at different points.
Minor, major axis and eccentricity
Semi major axis:
\(\displaystyle a={\frac {r_{\text{max}}+r_{\text{min}}}{2}}\)
Semi minor axis:
\(\displaystyle b={\sqrt {r_{\text{max}}r_{\text{min}}}}\)
Eccentricity:
\(\displaystyle e={\sqrt {1-{\frac {b^{2}}{a^{2}}}}}\)
https://en.wikipedia.org/wiki/Semi-major_and_semi-minor_axes
Orbital period
Orbital period is the amount of time required to complete one orbit turn. For example, Earth have orbital period equal to 1 year, Mercury - 0.24 years and Neptune - 164.8 years.
Orbital period can be calculated as:
\(\displaystyle T=2\pi\sqrt{a^3\over{\mu}}\)
where:
- \(\mu\) - standard gravitational parameter
- a - semi-major axis
I don’t use gravitational parameters in my orbit class, so my formula will be:
Polar coordinates
Polar coordinated are an easy way to work with round objects. They require angle and radius from heliocentric center. Heliocentric coordinates using Sun as a center. Angle in heliocentric polar coordinates will be true anomaly.
There are 3 types of anomalies:
- Mean (elapsed angle on circular orbit with same orbital period, if body moving at constant speed)
- Eccentric (elapsed angle on circular orbit with same orbital period)
- True anomaly (angle from sun to body)
To find true anomaly, we need to find mean anomaly and then eccentric anomaly.
Mean anomaly
Mean anomaly is a linear function. We just need to divide time by orbital period
\(\displaystyle M=\frac{2\pi t}{T}\)
Eccentric anomaly
Eccentric anomaly is pretty simple:
\(\displaystyle M=E-e\sin E\)
But this is a fun part: We need to calculate \(E\) in equation, which doesn’t have closed-form solution.
Simple equation above become not so simple:
\(\displaystyle E=M+2\sum _{n=1}^{\infty }{\frac {J_{n}(ne)}{n}}\sin(nM)\)
\(J_{n}(x)\) is the Bessel function:
\(\displaystyle J_{n}(x)=\sum _{m=0}^{\infty }{\frac {(-1)^{m}}{m!\Gamma (m+\alpha +1)}}{\left({\frac {x}{2}}\right)}^{2m+\alpha }\)
I took C# bessel implementation from here.
True anomaly
True anomaly is just a
Radius
Position
Precision of coordinates
You can control performance and precision by changing iterations in eccentric anomaly calculation. Orbits with high eccentricity require more iterations.
\(\displaystyle StdDev(1-\frac{M}{E-\epsilon\sin{E}})\), \(e \approx 0.97\)
Iterations | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
StdDev | 167.95% | 89.54% | 42.43% | 17.15% | 4.99% | 0.74% | 0.36% | 0.09% | 0.01% | 0.00% | 0.00% | 0.00% |
I’m using 32 iterations. It’s fine if orbit is not so stretched.
Equation is not linear because of Bessel function:
Multithreading
\(\sum\) can be easly parallelized. It’s a great place to use Unity job system. Note that job version have lot’s of allocations, which can be avoided in different scenarios.
Type | Basic | Jobs |
---|---|---|
time | 1539ms | 188ms |
orbits | 100k | 100k |
iter | 32 | 32 |