// ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global using System; using System.Diagnostics; namespace RGB.NET.Core; /// /// Represents a point consisting of a X- and a Y-position. /// [DebuggerDisplay("[X: {X}, Y: {Y}]")] public readonly struct Point : IEquatable { #region Constants private static readonly Point INVALID = new(float.NaN, float.NaN); /// /// Gets a [NaN,NaN]-Point. /// public static ref readonly Point Invalid => ref INVALID; #endregion #region Properties & Fields /// /// Gets the X-position of this . /// public float X { get; } /// /// Gets the Y-position of this . /// public float Y { get; } #endregion #region Constructors /// /// Initializes a new instance of the class using the provided values. /// /// The value used for the X-position. /// The value used for the Y-position. public Point(float x, float y) { this.X = x; this.Y = y; } #endregion #region Methods /// /// Converts the - and -position of this to a human-readable string. /// /// A string that contains the and of this . For example "[X: 100, Y: 20]". public override string ToString() => $"[X: {X}, Y: {Y}]"; /// /// Tests whether the specified is equivalent to this . /// /// The point to test. /// true if is equivalent to this ; otherwise, false. public bool Equals(Point other) => ((float.IsNaN(X) && float.IsNaN(other.X)) || X.EqualsInTolerance(other.X)) && ((float.IsNaN(Y) && float.IsNaN(other.Y)) || Y.EqualsInTolerance(other.Y)); /// /// 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 Point other && Equals(other); /// /// Returns a hash code for this . /// /// An integer value that specifies the hash code for this . public override int GetHashCode() => HashCode.Combine(X, Y); #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 ==(Point point1, Point point2) => point1.Equals(point2); /// /// 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 !=(Point point1, Point point2) => !(point1 == point2); /// /// Returns a new representing the addition of the two provided . /// /// The first . /// The second . /// A new representing the addition of the two provided . public static Point operator +(Point point1, Point point2) => new(point1.X + point2.X, point1.Y + point2.Y); /// /// Returns a new created from the provided and . /// /// The of the rectangle. /// The of the rectangle. /// The rectangle created from the provided and . public static Rectangle operator +(Point point, Size size) => new(point, size); /// /// Returns a new representing the subtraction of the two provided . /// /// The first . /// The second . /// A new representing the subtraction of the two provided . public static Point operator -(Point point1, Point point2) => new(point1.X - point2.X, point1.Y - point2.Y); /// /// Returns a new representing the multiplication of the two provided . /// /// The first . /// The second . /// A new representing the multiplication of the two provided . public static Point operator *(Point point1, Point point2) => new(point1.X * point2.X, point1.Y * point2.Y); /// /// Returns a new representing the division of the two provided . /// /// The first . /// The second . /// A new representing the division of the two provided . public static Point operator /(Point point1, Point point2) { if (point2.X.EqualsInTolerance(0) || point2.Y.EqualsInTolerance(0)) return Invalid; return new Point(point1.X / point2.X, point1.Y / point2.Y); } /// /// Returns a new representing the multiplication of the and the provided . /// /// The . /// The . /// A new representing the multiplication of the and the provided . public static Point operator *(Point point, Scale scale) => new(point.X * scale.Horizontal, point.Y * scale.Vertical); #endregion }