// 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
{
#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
}