diff --git a/scripts/orbits/IMassive.cs b/scripts/orbits/IMassive.cs
index a7d5f80..f5fac4b 100644
--- a/scripts/orbits/IMassive.cs
+++ b/scripts/orbits/IMassive.cs
@@ -3,5 +3,5 @@ using System;
public interface IMassive
{
- float Mass { get; }
+ double Mass { get; }
}
diff --git a/scripts/orbits/IMassiveExtensions.cs b/scripts/orbits/IMassiveExtensions.cs
new file mode 100644
index 0000000..6f4cf1a
--- /dev/null
+++ b/scripts/orbits/IMassiveExtensions.cs
@@ -0,0 +1,4 @@
+public static class IMassiveExtensions
+{
+ public static double U(this IMassive m) => Kepler.U(m.Mass);
+}
\ No newline at end of file
diff --git a/scripts/orbits/Orbit.cs b/scripts/orbits/Orbit.cs
index 3ebab6c..9e74201 100644
--- a/scripts/orbits/Orbit.cs
+++ b/scripts/orbits/Orbit.cs
@@ -2,56 +2,42 @@ using Godot;
using System;
using Vim.Math3d;
-public class Orbit
+public class Orbit : IOrbit
{
- // The position of the primary body relative to the ellipse - the
- // orbit itself is presented as being centred on the primary, but
- // all our math is elliptical.
- private DVector2 PrimaryPosition => Ellipse.Focus0;
+ public IEllipse Ellipse { get; set; }
- public Ellipse Ellipse { get; set; }
+ private readonly IMassive _massive;
+ private readonly ILocation _satellite;
- public DVector3 GetPosition(float t)
+ ///
+ /// An orbit is treated as one stationary body at one focus of the orbit's ellipse.
+ /// The satellite is treated as a massless point.
+ ///
+ /// Mass of the object being orbited
+ /// The orbiting body
+ public Orbit(IMassive massive, ILocation satellite)
{
- // TODO: determine period from mass of orbiting bodies
- var P = 10f;
+ // TODO: determine ellipse better
+ // semi-major axis is distance of satellite from origin
+ var a = satellite.Position.Magnitude();
+ var e = 0.8f;
+ this.Ellipse = new Ellipse(a, e);
+ _massive = massive;
+ _satellite = satellite;
+ }
+
+ public DVector3 GetPosition(double t)
+ {
var a = Ellipse.a;
var e = Ellipse.e;
+ var P = Kepler.GetPeriod(a, _massive.U());
+
var M = Kepler.GetMeanAnomaly(t, P);
var E = Kepler.GetEccentricAnomaly(e, M) + Math.PI;
var p = Kepler.GetEccentricPosition2D(e, a, t);
return new DVector3(p.X, 0, p.Y);
}
-
- public void Draw(ImmediateGeometry geo)
- {
- geo.Clear();
- geo.Begin(Mesh.PrimitiveType.LineLoop);
- DrawEllipse(geo);
- geo.End();
- }
-
- private void DrawEllipse(ImmediateGeometry geo)
- {
- geo.SetColor(new Color(1, 0, 0));
-
- int steps = 100;
-
- for (int i = 0; i < steps; i++)
- {
- float t = i / (float)steps;
- float a = t * Mathf.Tau;
-
- var v2 = Ellipse.Focus0 + Ellipse.GetPosition(a);
-
- geo.AddVertex(new Godot.Vector3
- {
- x = (float)v2.X,
- z = (float)v2.Y
- });
- }
- }
}
diff --git a/scripts/orbits/Planet.cs b/scripts/orbits/Planet.cs
index b12c0bc..815a8f9 100644
--- a/scripts/orbits/Planet.cs
+++ b/scripts/orbits/Planet.cs
@@ -6,7 +6,7 @@ using Vim.Math3d;
public class Planet : Spatial, IPointMass
{
[Export]
- public float Mass { get; set; }
+ public double Mass { get; set; }
private DVector3? _position;
public DVector3 Position