// ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global using System; using System.Diagnostics; namespace RGB.NET.Core; /// /// Represents an angular rotation. /// [DebuggerDisplay("[{" + nameof(Degrees) + "}°]")] public readonly struct Rotation : IEquatable { #region Constants private const float TWO_PI = MathF.PI * 2.0f; private const float RADIANS_DEGREES_CONVERSION = 180.0f / MathF.PI; private const float DEGREES_RADIANS_CONVERSION = MathF.PI / 180.0f; #endregion #region Properties & Fields /// /// Gets the angle in degrees. /// public float Degrees { get; } /// /// Gets the angle in radians. /// public float 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(float degrees) : this(degrees, degrees * DEGREES_RADIANS_CONVERSION) { } private Rotation(float degrees, float radians) { this.Degrees = degrees % 360.0f; this.Radians = radians % TWO_PI; } #endregion #region Methods /// /// Creates a new Rotation out of the specified degree-angle. /// /// The angle in degrees. /// The new rotation. public static Rotation FromDegrees(float degrees) => new(degrees); /// /// Creates a new Rotation out of the specified radian-angle. /// /// The angle in radians. /// The new rotation. public static Rotation FromRadians(float radians) => new(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 ==(in Rotation rotation1, in 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 !=(in Rotation rotation1, in 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 +(in Rotation rotation, float value) => new(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 -(in Rotation rotation, float value) => new(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 *(in Rotation rotation, float value) => new(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 /(in Rotation rotation, float value) => value.EqualsInTolerance(0) ? new Rotation(0) : new Rotation(rotation.Degrees / value); /// /// Converts a float to a . /// /// The rotation in degrees to convert. public static implicit operator Rotation(float rotation) => new(rotation); /// /// Converts to a float representing the rotation in degrees. /// /// The rotatio to convert. public static implicit operator float(in Rotation rotation) => rotation.Degrees; #endregion }