using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace RhythmBase.Components
{
///
/// Represents a rotated rectangle with non-integer coordinates.
///
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
public struct RDRotatedRectI(RDPointI? location, RDSizeI? size, RDPointI? pivot, float? angle = 0) : IEquatable
{
///
/// Gets or sets the location of the rectangle.
///
public RDPointI? Location { get; set; } = location;
///
/// Gets or sets the size of the rectangle.
///
public RDSizeI? Size { get; set; } = size;
///
/// Gets or sets the pivot point of the rotation.
///
public RDPointI? Pivot { get; set; } = pivot;
///
/// Gets or sets the angle of rotation in degrees.
///
public float? Angle { get; set; } = angle;
///
/// Gets the rectangle without rotation.
///
public readonly RDRectI? WithoutRotate => Location is null && Pivot is null && Size is null ? null : new(Location - (RDSizeI?)Pivot, Size);
///
/// IItializes a new instance of the struct.
///
/// The rectangle.
/// The pivot point.
/// The angle of rotation.
public RDRotatedRectI(RDRectI? rect, RDPointI? pivot, float angle) : this(rect?.Location, rect?.Size, pivot, angle) { }
///
/// IItializes a new instance of the struct.
///
/// The rectangle.
public RDRotatedRectI(RDRectI? rect) : this(rect?.Location, rect?.Size, null, 0f) { }
///
/// Inflates the specified rectangle by the specified size.
///
/// The rectangle to inflate.
/// The size to inflate by.
/// The inflated rectangle.
public static RDRotatedRectI Inflate(RDRotatedRectI rect, RDSizeI size)
{
RDRotatedRectI result = rect;
result.Inflate(size);
return result;
}
///
/// Inflates the specified rectangle by the specified width and height.
///
/// The rectangle to inflate.
/// The width to inflate by.
/// The height to inflate by.
/// The inflated rectangle.
public static RDRotatedRectI Inflate(RDRotatedRectI rect, int x, int y)
{
RDRotatedRectI result = rect;
result.Inflate(x, y);
return result;
}
///
/// Offsets the rectangle by the specified x and y values.
///
/// The x value to offset by.
/// The y value to offset by.
public void Offset(int? x, int? y) => Location += (RDSizeI)new RDPointI(x, y);
///
/// Offsets the rectangle by the specified point.
///
/// The point to offset by.
public void Offset(RDPointI p) => Offset(p.X, p.Y);
///
/// Inflates the rectangle by the specified size.
///
/// The size to inflate by.
public void Inflate(RDSizeI size)
{
Size += new RDSizeI(size.Width * 2, size.Height * 2);
Pivot -= (RDSizeI)new RDPointI(size.Width, size.Height);
}
///
/// Inflates the rectangle by the specified width and height.
///
/// The width to inflate by.
/// The height to inflate by.
public void Inflate(int width, int height)
{
Size += new RDSizeI(width * 2, height * 2);
Pivot -= (RDSizeI)new RDPointI(width, height);
}
///
public static bool operator ==(RDRotatedRectI rect1, RDRotatedRectI rect2) => rect1.Equals(rect2);
///
public static bool operator !=(RDRotatedRectI rect1, RDRotatedRectI rect2) => !rect1.Equals(rect2);
///
public override readonly bool Equals([NotNullWhen(true)] object? obj) => obj is RDRotatedRectI e && Equals(e);
///
public override readonly int GetHashCode() => HashCode.Combine(Location, Size, Pivot, Angle);
///
public override readonly string ToString() => $"{{Location=[{Location}],Size=[{Size}],Pivot[{Pivot}],Angle={Angle}}}";
///
public readonly bool Equals(RDRotatedRectI other) =>
Location == other.Location &&
Size == other.Size && Pivot
== other.Pivot &&
Angle == other.Angle;
private readonly string GetDebuggerDisplay() => ToString();
}
}