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); } }