Files
Syntriax.Engine/Engine.Core/Primitives/AABB2D.cs

112 lines
4.9 KiB
C#

using System;
using System.Collections.Generic;
namespace Engine.Core;
/// <summary>
/// Represents an Axis-Aligned Bounding Box (AABB) in 2D space.
/// </summary>
/// <param name="lowerBoundary">The lower boundary of the <see cref="AABB2D"/>.</param>
/// <param name="upperBoundary">The upper boundary of the <see cref="AABB2D"/>.</param>
/// <remarks>
/// Initializes a new instance of the <see cref="AABB2D"/> struct with the specified lower and upper boundaries.
/// </remarks>
[System.Diagnostics.DebuggerDisplay("LowerBoundary: {LowerBoundary.ToString(), nq}, UpperBoundary: {UpperBoundary.ToString(), nq}")]
public readonly struct AABB2D(Vector2D lowerBoundary, Vector2D upperBoundary) : IEquatable<AABB2D>
{
/// <summary>
/// The lower boundary of the <see cref="AABB2D"/>.
/// </summary>
public readonly Vector2D LowerBoundary = lowerBoundary;
/// <summary>
/// The upper boundary of the <see cref="AABB2D"/>.
/// </summary>
public readonly Vector2D UpperBoundary = upperBoundary;
/// <summary>
/// Gets the center point of the <see cref="AABB2D"/>.
/// </summary>
public readonly Vector2D Center => (LowerBoundary + UpperBoundary) * .5f;
/// <summary>
/// Gets the size of the <see cref="AABB2D"/>.
/// </summary>
public readonly Vector2D Size => LowerBoundary.FromTo(UpperBoundary).Abs();
/// <summary>
/// Gets half the size of the <see cref="AABB2D"/>.
/// </summary>
public readonly Vector2D SizeHalf => Size * .5f;
public static bool operator ==(AABB2D left, AABB2D right) => left.UpperBoundary == right.UpperBoundary && left.LowerBoundary == right.LowerBoundary;
public static bool operator !=(AABB2D left, AABB2D right) => left.UpperBoundary != right.UpperBoundary || left.LowerBoundary != right.LowerBoundary;
/// <summary>
/// Creates an <see cref="AABB2D"/> from a collection of <see cref="Vector2D"/>s.
/// </summary>
/// <param name="vectors">The collection of <see cref="Vector2D"/>s.</param>
/// <returns>An <see cref="AABB2D"/> that bounds all the <see cref="Vector2D"/>s.</returns>
public static AABB2D FromVectors(IEnumerable<Vector2D> vectors)
{
int counter = 0;
Vector2D lowerBoundary = new(float.MaxValue, float.MaxValue);
Vector2D upperBoundary = new(float.MinValue, float.MinValue);
foreach (Vector2D vector in vectors)
{
lowerBoundary = Vector2D.Min(lowerBoundary, vector);
upperBoundary = Vector2D.Max(upperBoundary, vector);
counter++;
}
if (counter < 2)
throw new ArgumentException($"Parameter {nameof(vectors)} must have at least 2 items.");
return new(lowerBoundary, upperBoundary);
}
/// <summary>
/// Checks if two <see cref="AABB2D"/>s are approximately equal.
/// </summary>
/// <param name="left">The first <see cref="AABB2D"/>.</param>
/// <param name="right">The second <see cref="AABB2D"/>.</param>
/// <param name="epsilon">The epsilon range.</param>
/// <returns><see cref="true"/> if the <see cref="AABB2D"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
public static bool ApproximatelyEquals(AABB2D left, AABB2D right, float epsilon = float.Epsilon)
=> left.LowerBoundary.ApproximatelyEquals(right.LowerBoundary, epsilon) && left.UpperBoundary.ApproximatelyEquals(right.UpperBoundary, epsilon);
/// <summary>
/// Determines whether the specified object is equal to the current <see cref="AABB2D"/>.
/// </summary>
/// <param name="obj">The object to compare with the current <see cref="AABB2D"/>.</param>
/// <returns><see cref="true"/> if the specified object is equal to the current <see cref="AABB2D"/>; otherwise, <see cref="false"/>.</returns>
public override bool Equals(object? obj) => obj is AABB2D aabb && this == aabb;
public bool Equals(AABB2D other) => this == other;
/// <summary>
/// Generates a hash code for the <see cref="AABB2D"/>.
/// </summary>
/// <returns>A hash code for the <see cref="AABB2D"/>.</returns>
public override int GetHashCode() => System.HashCode.Combine(LowerBoundary, UpperBoundary);
/// <summary>
/// Converts the <see cref="AABB2D"/> to its string representation.
/// </summary>
/// <returns>A string representation of the <see cref="AABB2D"/>.</returns>
public override string ToString() => $"{nameof(AABB2D)}({LowerBoundary}, {UpperBoundary})";
}
/// <summary>
/// Provides extension methods for the <see cref="AABB2D"/> struct.
/// </summary>
public static class AABBExtensions
{
/// <inheritdoc cref="AABB2D.FromVectors" />
public static AABB2D ToAABB(this IEnumerable<Vector2D> vectors) => AABB2D.FromVectors(vectors);
/// <inheritdoc cref="AABB2D.ApproximatelyEquals" />
public static bool ApproximatelyEquals(this AABB2D left, AABB2D right, float epsilon = float.Epsilon) => AABB2D.ApproximatelyEquals(left, right, epsilon);
}