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