using Godot; using System; using Vim.Math3d; public struct Ellipse : IEllipse { 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 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) }; } /// /// 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 { get; } /// /// 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 { get; } public DVector2[] Foci { get; } 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); } }