Compare commits

...

2 Commits

Author SHA1 Message Date
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
5 changed files with 78 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

@ -2,7 +2,7 @@ using Godot;
using System;
using Vim.Math3d;
public struct Ellipse
public struct Ellipse : IEllipse
{
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
// in the constructor to avoid recalculating properties whenever
// 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>
@ -29,8 +39,7 @@ public struct Ellipse
/// <summary>
/// Semi-minor axis
/// </summary>
public double b => SemiMinorAxis;
public double SemiMinorAxis => Math.Sqrt(Apisides.max * Apisides.min);
public double b { get; }
/// <summary>
/// Get a position on the auxiliary circle
@ -40,13 +49,10 @@ public struct Ellipse
public DVector2 GetAuxiliaryPosition2D(double t = 0) =>
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) =>
new DVector2(Math.Cos(t) * a, Math.Sin(t) * b);
public DVector2[] Foci { get; }
public DVector2 Focus0 => new DVector2(-GetFocusDistance(), 0);
public DVector2 Focus1 => new DVector2(GetFocusDistance(), 0);
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);
}