// ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global using System; using System.Diagnostics; namespace RGB.NET.Core { /// /// Represents an angular rotation. /// [DebuggerDisplay("[{Degrees}°]")] public struct Rotation { #region Constants private const double TWO_PI = Math.PI * 2.0; private const double RADIANS_DEGREES_CONVERSION = 180.0 / Math.PI; private const double DEGREES_RADIANS_CONVERSION = Math.PI / 180.0; #endregion #region Properties & Fields /// /// Gets the angle in degrees. /// public double Degrees { get; } /// /// Gets the angle in radians. /// public double Radians { get; } /// /// Gets a bool indicating if the rotation is > 0. /// public bool IsRotated => !Degrees.EqualsInTolerance(0); #endregion #region Constructors /// /// Initializes a new instance of the class using the provided values. /// /// The rotation in degrees. public Rotation(double degrees) : this(degrees, degrees * DEGREES_RADIANS_CONVERSION) { } private Rotation(double degrees, double radians) { this.Degrees = degrees % 360.0; this.Radians = radians % TWO_PI; } #endregion #region Methods /// /// Creates a new Rotation out of the given degree-angle. /// /// The angle in degrees. /// The new rotation. public static Rotation FromDegrees(double degrees) => new Rotation(degrees); /// /// Creates a new Rotation out of the given radian-angle. /// /// The angle in radians. /// The new rotation. public static Rotation FromRadians(double radians) => new Rotation(radians * RADIANS_DEGREES_CONVERSION, radians); /// /// Tests whether the specified is equivalent to this . /// /// The rotation to test. /// true if is equivalent to this ; otherwise, false. public bool Equals(Rotation other) => Degrees.EqualsInTolerance(other.Degrees); /// /// Tests whether the specified object is a and is equivalent to this . /// /// The object to test. /// true if is a equivalent to this ; otherwise, false. public override bool Equals(object obj) => obj is Rotation other && Equals(other); /// /// Returns a hash code for this . /// /// An integer value that specifies the hash code for this . public override int GetHashCode() => Degrees.GetHashCode(); #endregion #region Operators /// /// Returns a value that indicates whether two specified are equal. /// /// The first to compare. /// The second to compare. /// true if and are equal; otherwise, false. public static bool operator ==(Rotation rotation1, Rotation rotation2) => rotation1.Equals(rotation2); /// /// Returns a value that indicates whether two specified are equal. /// /// The first to compare. /// The second to compare. /// true if and are not equal; otherwise, false. public static bool operator !=(Rotation rotation1, Rotation rotation2) => !(rotation1 == rotation2); /// /// Returns a new representing the addition of the and the provided value. /// /// The . /// The value to add. /// A new representing the addition of the and the provided value. public static Rotation operator +(Rotation rotation, double value) => new Rotation(rotation.Degrees + value); /// /// Returns a new representing the subtraction of the and the provided value. /// /// The . /// The value to substract. /// A new representing the subtraction of the and the provided value. public static Rotation operator -(Rotation rotation, double value) => new Rotation(rotation.Degrees - value); /// /// Returns a new representing the multiplication of the and the provided value. /// /// The . /// The value to multiply with. /// A new representing the multiplication of the and the provided value. public static Rotation operator *(Rotation rotation, double value) => new Rotation(rotation.Degrees * value); /// /// Returns a new representing the division of the and the provided value. /// /// The . /// The value to device with. /// A new representing the division of the and the provided value. public static Rotation operator /(Rotation rotation, double value) => value.EqualsInTolerance(0) ? new Rotation(0) : new Rotation(rotation.Degrees / value); /// /// Converts a double to a . /// /// The rotation in degrees to convert. public static implicit operator Rotation(double rotation) => new Rotation(rotation); /// /// Converts to a double representing the rotation in degrees. /// /// The rotatio to convert. public static implicit operator double(Rotation rotation) => rotation.Degrees; #endregion } }