Compare commits

...

3 Commits

Author SHA1 Message Date
ktyl acfd70841f WIP RESET THIS 2022-09-07 00:55:16 +01:00
ktyl 5ad70b3f9c extract IOrbit and IOrbitExtensions 2022-09-07 00:54:22 +01:00
ktyl bed71f2c4c extract IEllipse and extensions 2022-09-07 00:53:56 +01:00
7 changed files with 137 additions and 8 deletions

7
scripts/orbits/IOrbit.cs Normal file
View File

@ -0,0 +1,7 @@
using Vim.Math3d;
public interface IOrbit
{
DVector3 GetPosition(double t);
IEllipse Ellipse { get; set; }
}

View File

@ -0,0 +1,29 @@
using Godot;
public static class IOrbitExtensions
{
public static void Draw(this IOrbit orbit, ImmediateGeometry geo)
{
geo.Clear();
geo.Begin(Mesh.PrimitiveType.LineLoop);
geo.SetColor(new Color(1, 0, 0));
int steps = 100;
var ellipse = orbit.Ellipse;
for (int i = 0; i < steps; i++)
{
float t = i / (float)steps;
float a = t * Mathf.Tau;
var v2 = ellipse.Foci[0] + ellipse.GetPosition(a);
geo.AddVertex(new Godot.Vector3
{
x = (float)v2.X,
z = (float)v2.Y
});
}
geo.End();
}
}

View File

@ -0,0 +1,13 @@
using Vim.Math3d;
using static System.Math;
public static class IOrbitalElementsExtensions
{
/// <summary>
/// Get the Cartesian position on the orbit for a given mean anomaly.
/// </summary>
/// <param name="M">Mean anomaly</param>
/// <returns>Position</returns>
public static DVector2 GetEccentricPosition2D(this OrbitalElements elements, double M) =>
Kepler.GetEccentricPosition2D(elements.e, elements.a, M);
}

View File

@ -0,0 +1,46 @@
public struct OrbitalElements
{
private Ellipse _ellipse;
/// <summary>
/// Semi-major axis in AU
/// </summary>
public double a => _ellipse.a;
/// <summary>
/// Eccentricity
/// </summary>
public double e => _ellipse.e;
/// <summary>
/// Inclination in degrees
/// </summary>
public double i { get; private set; }
/// <summary>
/// Argument of ascending node in degrees
/// </summary>
public double W { get; private set; }
/// <summary>
/// Argument of periapsis in degrees
/// </summary>
public double p { get; private set; }
/// <summary>
/// Mean anomaly at epoch
/// </summary>
public double M0 { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="a">Semi-major axis in AU</param>
/// <param name="e">eccentricity</param>
/// <param name="i">Inclination in degrees</param>
/// <param name="W">Argument of ascending node in degrees</param>
/// <param name="p">Argument of periapsis in degrees</param>
/// <param name="M0">Mean anomaly at epoch</param>
public OrbitalElements(double a, double e, double i, double W, double p, double M0)
{
_ellipse = new Ellipse(a, e);
this.i = i;
this.W = W;
this.p = p;
this.M0 = M0;
}
}

View File

@ -2,7 +2,7 @@ using Godot;
using System; using System;
using Vim.Math3d; using Vim.Math3d;
public struct Ellipse public struct Ellipse : IEllipse
{ {
public Ellipse(double a = 1, double e = 0) public Ellipse(double a = 1, double e = 0)
{ {
@ -12,6 +12,16 @@ public struct Ellipse
// TODO: this is an immutable struct, so initialise everything else // TODO: this is an immutable struct, so initialise everything else
// in the constructor to avoid recalculating properties whenever // in the constructor to avoid recalculating properties whenever
// they are accessed // they are accessed
Apisides = new Apisides(a, e);
b = Math.Sqrt(Apisides.max * Apisides.min);
var d = Math.Sqrt(a * a - b * b);
Foci = new DVector2[]
{
new DVector2(-d, 0),
new DVector2(d, 0)
};
} }
/// <summary> /// <summary>
@ -29,8 +39,7 @@ public struct Ellipse
/// <summary> /// <summary>
/// Semi-minor axis /// Semi-minor axis
/// </summary> /// </summary>
public double b => SemiMinorAxis; public double b { get; }
public double SemiMinorAxis => Math.Sqrt(Apisides.max * Apisides.min);
/// <summary> /// <summary>
/// Get a position on the auxiliary circle /// Get a position on the auxiliary circle
@ -40,13 +49,10 @@ public struct Ellipse
public DVector2 GetAuxiliaryPosition2D(double t = 0) => public DVector2 GetAuxiliaryPosition2D(double t = 0) =>
new DVector2(Math.Cos(t), Math.Sin(t)) * a; new DVector2(Math.Cos(t), Math.Sin(t)) * a;
private Apisides Apisides => new Apisides(a, e); private Apisides Apisides { get; }
public DVector2 GetPosition(double t) => public DVector2[] Foci { get; }
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); private double GetFocusDistance() => Math.Sqrt(a * a - b * b);
} }

View File

@ -0,0 +1,20 @@
using Godot;
using System;
using Vim.Math3d;
public interface IEllipse
{
/// <summary>
/// Semi-major axis
/// </summary>
double a { get; }
double b { get; }
/// <summary>
/// Eccentricity
/// </summary>
double e { get; }
/// <summary>
/// Positions of the two foci of the ellipse
/// </summary>
DVector2[] Foci { get; }
}

View File

@ -0,0 +1,8 @@
using Vim.Math3d;
using System;
public static class IEllipseExtensions
{
public static DVector2 GetPosition(this IEllipse e, double t) =>
new DVector2(Math.Cos(t) * e.a, Math.Sin(t) * e.b);
}