using DecimalMath; using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Units; using T = Angle; public readonly struct Angle { public static String Unit => "rad"; public static String Symbol => "∠"; public static readonly Angle Pi = new Angle(DecimalEx.Pi); public Decimal Value { get; } public Angle(Decimal value) { var modulo = value.Modulo(DecimalEx.TwoPi); Value = modulo > DecimalEx.Pi ? modulo - DecimalEx.TwoPi : modulo; } public override String ToString() => Value + Unit; #region scalar multiplication public static Angle operator *(Decimal scalar, Angle angle ) => new Angle(scalar * angle.Value); public static Angle operator *(Angle angle , Decimal scalar) => new Angle(scalar * angle.Value); public static Angle operator /(Angle angle , Decimal scalar) => new Angle(angle.Value / scalar); #endregion #region addition public static T operator +(T left, T right) => new T(left.Value + right.Value); public static T operator -(T left, T right) => new T(left.Value - right.Value); public static T operator -(T t) => new T(-t.Value); #endregion #region compare public static Boolean operator ==(T left, T right) => left.Value == right.Value; public static Boolean operator !=(T left, T right) => left.Value != right.Value; public static Boolean operator > (T left, T right) => left.Value > right.Value; public static Boolean operator < (T left, T right) => left.Value < right.Value; public static Boolean operator >=(T left, T right) => left.Value >= right.Value; public static Boolean operator <=(T left, T right) => left.Value <= right.Value; #endregion #region conversion public static implicit operator T(Decimal d) => new T(d); public static implicit operator T(Double d) => new T((Decimal)d); public static implicit operator T(Int32 i) => new T(i); public static implicit operator Decimal(T t) => t.Value; #endregion #region equality public override Boolean Equals(Object? obj) => obj is T other && Equals(other); public override Int32 GetHashCode() => Value.GetHashCode(); #endregion }