diff --git a/scenes/Main.tscn b/scenes/Main.tscn
index 990a849..da3587b 100644
--- a/scenes/Main.tscn
+++ b/scenes/Main.tscn
@@ -1,19 +1,14 @@
-[gd_scene load_steps=4 format=2]
+[gd_scene load_steps=3 format=2]
-[ext_resource path="res://scenes/Train.tscn" type="PackedScene" id=1]
-[ext_resource path="res://scenes/Railway.tscn" type="PackedScene" id=2]
[ext_resource path="res://scenes/OrbitCamera.tscn" type="PackedScene" id=3]
+[ext_resource path="res://scenes/OrbitSystem.tscn" type="PackedScene" id=4]
[node name="Main" type="Node2D"]
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( 0.515898, 0.606099, -0.605386, -0.393123, 0.795389, 0.461314, 0.76112, -2.26831e-08, 0.648611, 0, 0, 0 )
+visible = false
-[node name="OrbitCamera" parent="." instance=ExtResource( 3 )]
-_speed = 0.5
+[node name="Camera" parent="." instance=ExtResource( 3 )]
-[node name="Railway" parent="." instance=ExtResource( 2 )]
-
-[node name="Train" parent="." instance=ExtResource( 1 )]
-_speed = 5.0
-_railwayPath = NodePath("../Railway")
+[node name="Orbit System" parent="." instance=ExtResource( 4 )]
diff --git a/scripts/orbits/Orbit.cs b/scripts/orbits/Orbit.cs
new file mode 100644
index 0000000..0aca13e
--- /dev/null
+++ b/scripts/orbits/Orbit.cs
@@ -0,0 +1,12 @@
+using Godot;
+using System;
+
+public class Orbit
+{
+ public Orbit(PointMass a, PointMass b)
+ {
+
+ }
+
+ // ellipse
+}
diff --git a/scripts/orbits/OrbitSystem.cs b/scripts/orbits/OrbitSystem.cs
index 358ad53..61a432a 100644
--- a/scripts/orbits/OrbitSystem.cs
+++ b/scripts/orbits/OrbitSystem.cs
@@ -26,7 +26,9 @@ public class OrbitSystem : Node, IMassive, ILocation
public float Mass { get; } = 1;
- private ImmediateGeometry _orbit;
+ private Orbit _orbit;
+
+ private ImmediateGeometry _orbitGeometry;
public override void _Ready()
{
@@ -39,35 +41,45 @@ public class OrbitSystem : Node, IMassive, ILocation
DrawOrbit();
}
+ private void InitOrbit()
+ {
+
+ }
+
private void DrawOrbit()
{
int steps = 100;
- _orbit.Clear();
- _orbit.Begin(Mesh.PrimitiveType.LineLoop);
- _orbit.SetColor(new Color(1, 0, 0));
+ _orbitGeometry.Clear();
+ _orbitGeometry.Begin(Mesh.PrimitiveType.LineLoop);
+ _orbitGeometry.SetColor(new Color(1, 0, 0));
+
+ var ellipse = new Ellipse(1, .5);
+
for (int i = 0; i < steps; i++)
{
float t = i / (float)steps;
float a = t * Mathf.Tau;
- _orbit.AddVertex(new Vector3
+ var v2 = ellipse.Focus0 + ellipse.GetPosition(a);
+
+ _orbitGeometry.AddVertex(new Vector3
{
- x = Mathf.Sin(a),
- z = Mathf.Cos(a)
+ x = (float)v2.X,
+ z = (float)v2.Y
});
}
- _orbit.End();
+ _orbitGeometry.End();
}
private void InitGeometry()
{
- _orbit = new ImmediateGeometry();
+ _orbitGeometry = new ImmediateGeometry();
var m = new SpatialMaterial();
m.VertexColorUseAsAlbedo = true;
m.FlagsUnshaded = true;
- _orbit.MaterialOverride = m;
- AddChild(_orbit);
+ _orbitGeometry.MaterialOverride = m;
+ AddChild(_orbitGeometry);
}
private void InitPointMasses()
diff --git a/scripts/orbits/Planet.cs b/scripts/orbits/Planet.cs
index c93a33a..877455f 100644
--- a/scripts/orbits/Planet.cs
+++ b/scripts/orbits/Planet.cs
@@ -1,7 +1,7 @@
using Godot;
using System;
-public class Planet : Node
+public class Planet : Node, IMassive
{
[Export]
public float Mass { get; set; }
diff --git a/scripts/orbits/PointMass.cs b/scripts/orbits/PointMass.cs
index bb277c1..bbeaa14 100644
--- a/scripts/orbits/PointMass.cs
+++ b/scripts/orbits/PointMass.cs
@@ -1,6 +1,6 @@
using Godot;
-struct PointMass : IMassive, ILocation
+public struct PointMass : IMassive, ILocation
{
public float Mass => _massive == null ? _mass : _massive.Mass;
public Vector3 Position => _spatial.Translation;
diff --git a/scripts/orbits/math/Ellipse.cs b/scripts/orbits/math/Ellipse.cs
new file mode 100644
index 0000000..e1fff2e
--- /dev/null
+++ b/scripts/orbits/math/Ellipse.cs
@@ -0,0 +1,63 @@
+using Godot;
+using System;
+using Vim.Math3d;
+
+public struct Ellipse
+{
+ public Ellipse(double a = 1, double e = 0)
+ {
+ SemiMajorAxis = a;
+ Eccentricity = e;
+
+ // TODO: this is an immutable struct, so initialise everything else
+ // in the constructor to avoid recalculating properties whenever
+ // they are accessed
+ }
+
+ ///
+ /// Semi-major axis
+ ///
+ public double a => SemiMajorAxis;
+ public double SemiMajorAxis { get; }
+
+ ///
+ /// Eccentricity
+ ///
+ public double e => Eccentricity;
+ public double Eccentricity { get; }
+
+ ///
+ /// Semi-minor axis
+ ///
+ public double b => SemiMinorAxis;
+ public double SemiMinorAxis => Math.Sqrt(Apisides.max * Apisides.min);
+
+ ///
+ /// Get a position on the auxiliary circle
+ ///
+ /// Angle in radians around the circle
+ /// 2D position on the circle scaled by the semi-major axis
+ public DVector2 GetAuxiliaryPosition2D(double t = 0) =>
+ new DVector2(Math.Cos(t), Math.Sin(t)) * a;
+
+ private Apisides Apisides => new Apisides(a, e);
+
+ public DVector2 GetPosition(double t) =>
+ new DVector2(Math.Cos(t) * a, Math.Sin(t) * b);
+
+ public DVector2 Focus0 => new DVector2(-GetFocusDistance(), 0);
+ public DVector2 Focus1 => new DVector2(GetFocusDistance(), 0);
+ private double GetFocusDistance() => Math.Sqrt(a * a - b * b);
+}
+
+public struct Apisides
+{
+ public readonly double min;
+ public readonly double max;
+
+ public Apisides(double a, double e)
+ {
+ min = a * (1 - e);
+ max = a * (1 + e);
+ }
+}
\ No newline at end of file