diff --git a/src/DtronixCommon/Boundary.cs b/src/DtronixCommon/Boundary.cs
new file mode 100644
index 0000000..d7433ba
--- /dev/null
+++ b/src/DtronixCommon/Boundary.cs
@@ -0,0 +1,370 @@
+using System.Runtime.CompilerServices;
+
+namespace DtronixCommon;
+
+///
+/// Boundary represented as [MinX, MinY] (Bottom Left) and [MaxX, MaxY] (Top Right) points.
+///
+///
+/// MinY could be down and MaxY up as in cartesian coordinates, or vice vercia as is common
+/// in screen coordinates. Depends upon which system was selected for use.
+///
+public readonly struct Boundary
+{
+ ///
+ /// Minimum X coordinate position. (Left)
+ ///
+ public readonly float MinX;
+
+ ///
+ /// Minimum Y coordinate position (Bottom/Top)
+ ///
+ public readonly float MinY;
+
+ ///
+ /// Maximum X coordinate position (Right)
+ ///
+ public readonly float MaxX;
+
+ ///
+ /// Maximum Y coordinate position (Top/Bottom)
+ ///
+ public readonly float MaxY;
+
+ ///
+ /// Width of the boundary.
+ ///
+ public readonly float Width => MaxX - MinX;
+
+ ///
+ /// Height of the boundary.
+ ///
+ public readonly float Height => MaxY - MinY;
+
+ ///
+ /// Maximum sized boundary.
+ ///
+ public static Boundary Max { get; } = new(
+ float.MinValue,
+ float.MinValue,
+ float.MaxValue,
+ float.MaxValue);
+
+ ///
+ /// Half the maximum size of the boundary.
+ ///
+ public static Boundary HalfMax { get; } = new(
+ float.MinValue / 2,
+ float.MinValue / 2,
+ float.MaxValue / 2,
+ float.MaxValue / 2);
+
+ ///
+ /// Zero sized boundary.
+ ///
+ public static Boundary Zero { get; } = new(0, 0, 0, 0);
+
+ ///
+ /// Empty boundary.
+ ///
+ public static Boundary Empty { get; } = new(
+ float.PositiveInfinity,
+ float.PositiveInfinity,
+ float.NegativeInfinity,
+ float.NegativeInfinity);
+
+ ///
+ /// Returns true if the boundary has no volume.
+ ///
+ public bool IsEmpty => MinY >= MaxY || MinX >= MaxX;
+
+ ///
+ /// Creates a boundary with the specified left, bottom, right, top distances from origin.
+ ///
+ /// Left distance from origin.
+ /// Bottom distance from origin.
+ /// Right distance from origin.
+ /// Top distance from origin.
+ public Boundary(float minX, float minY, float maxX, float maxY)
+ {
+ MinX = minX;
+ MinY = minY;
+ MaxX = maxX;
+ MaxY = maxY;
+ }
+
+ ///
+ /// IntersectsWith - Returns true if the Boundary intersects with this Boundary
+ /// Returns false otherwise.
+ /// Note that if one edge is coincident, this is considered an intersection.
+ ///
+ ///
+ /// Returns true if the Boundary intersects with this Boundary
+ /// Returns false otherwise.
+ ///
+ /// Rect
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool IntersectsWith(in Boundary boundary)
+ {
+ return boundary.MinX <= MaxX &&
+ boundary.MaxX >= MinX &&
+ boundary.MinY <= MaxY &&
+ boundary.MaxY >= MinY;
+ }
+
+ ///
+ /// IntersectsWith - Returns true if the Boundary intersects with this Boundary
+ /// Returns false otherwise.
+ /// Note that if one edge is coincident, this is considered an intersection.
+ ///
+ /// First boundary.
+ /// Second boundary.
+ ///
+ /// Returns true if the Boundary intersects with this Boundary
+ /// Returns false otherwise.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool Intersects(in Boundary boundary1, in Boundary boundary2)
+ {
+ return boundary1.MinX <= boundary2.MaxX &&
+ boundary1.MaxX >= boundary2.MinX &&
+ boundary1.MinY <= boundary2.MaxY &&
+ boundary1.MaxY >= boundary2.MinY;
+ }
+
+ ///
+ /// Checks if a point is contained by the boundary.
+ ///
+ /// X coordinate.
+ /// Y coordinate.
+ /// True if the point is contained, false otherwise.
+ public bool Contains(float x, float y)
+ {
+ return x >= MinX
+ && x <= MaxX
+ && y >= MinY
+ && y <= MaxY;
+ }
+
+
+ ///
+ /// Takes the current boundary and offsets it by the specified X & Y vectors.
+ ///
+ /// X vector offset.
+ /// Y vector offset.
+ /// New offset boundary.
+ public Boundary CreateOffset(in float x, in float y)
+ {
+ return new Boundary(
+ (float)(MinX + x),
+ (float)(MinY + y),
+ (float)(MaxX + x),
+ (float)(MaxY + y));
+ }
+
+ ///
+ /// Creates a union between two boundaries.
+ ///
+ /// second boundary to union with.
+ /// new union boundary.
+ public Boundary Union(in Boundary boundary)
+ {
+ if (IsEmpty)
+ return boundary;
+
+ if (boundary.IsEmpty)
+ return this;
+
+ return new Boundary(
+ Math.Min(MinX, boundary.MinX),
+ Math.Min(MinY, boundary.MinY),
+ Math.Max(MaxX, boundary.MaxX),
+ Math.Max(MaxY, boundary.MaxY));
+ }
+
+ ///
+ /// Gets a rough approximation of the hypotenuse of the rectangle.
+ /// Uses different algorithms based upon the passed integer.
+ ///
+ /// 0 - 3. Determines algorithm used. 0 is the fastest, 3 is the slowest but most accurate.
+ /// Approximate length
+ ///
+ /// https://stackoverflow.com/a/26607206
+ /// All these assume 0 ≤ a ≤ b.
+ /// 0. h = b + 0.337 * a // less sorting order of the a & b variables;
+ /// 1. h = b + 0.337 * a // max error ≈ 5.5 %
+ /// 2. h = max(b, 0.918 * (b + (a >> 1))) // max error ≈ 2.6 %
+ /// 3. h = b + 0.428 * a* a / b // max error ≈ 1.04 %
+ ///
+ public float GetHypotenuseApproximate(int algorithm)
+ {
+ var a = MathF.Abs(MaxX - MinX);
+ var b = MathF.Abs(MaxY - MinY);
+
+ if (algorithm == 0)
+ return b + 0.337f * a;
+
+ // Transpose variables to ensure "b" is larger than A
+ if (a > b)
+ (a, b) = (b, a);
+
+ switch (algorithm)
+ {
+ case 1:
+ return b + 0.337f * a;
+ case 2:
+ return MathF.Max(b, 0.918f * (b + (a / 2f)));
+ case 3:
+ return b + 0.428f * a * a / b;
+ default:
+ throw new ArgumentException("Must select algorithm 0 through 3", nameof(algorithm));
+ }
+
+ }
+
+ ///
+ /// Rotates the boundary from its center point by the specified number of degrees.
+ ///
+ /// Degrees to rotate.
+ /// New rotated boundary.
+ public Boundary Rotate(float degrees)
+ {
+ // Center position of the rectangle.
+ //private const m_PosX : Number, m_PosY : Number;
+
+ // Rectangle orientation, in radians.
+ var m_Orientation = degrees * MathF.PI / 180.0f;
+ // Half-width and half-height of the rectangle.
+ var m_HalfSizeX = Width / 2;
+ var m_HalfSizeY = Height / 2;
+ var m_PosX = MinX + m_HalfSizeX;
+ var m_PosY = MinY + m_HalfSizeY;
+
+ // corner_1 is right-top corner of unrotated rectangle, relative to m_Pos.
+ // corner_2 is right-bottom corner of unrotated rectangle, relative to m_Pos.
+ var corner_1_x = m_HalfSizeX;
+ var corner_2_x = m_HalfSizeX;
+ var corner_1_y = -m_HalfSizeY;
+ var corner_2_y = m_HalfSizeY;
+
+ var sin_o = MathF.Sin(m_Orientation);
+ var cos_o = MathF.Cos(m_Orientation);
+
+ // xformed_corner_1, xformed_corner_2 are points corner_1, corner_2 rotated by angle m_Orientation.
+ var xformed_corner_1_x = corner_1_x * cos_o - corner_1_y * sin_o;
+ var xformed_corner_1_y = corner_1_x * sin_o + corner_1_y * cos_o;
+ var xformed_corner_2_x = corner_2_x * cos_o - corner_2_y * sin_o;
+ var xformed_corner_2_y = corner_2_x * sin_o + corner_2_y * cos_o;
+
+ // ex, ey are extents (half-sizes) of the final AABB.
+ var ex = MathF.Max(MathF.Abs(xformed_corner_1_x), MathF.Abs(xformed_corner_2_x));
+ var ey = MathF.Max(MathF.Abs(xformed_corner_1_y), MathF.Abs(xformed_corner_2_y));
+ return new Boundary(m_PosX - ex, m_PosY - ey, m_PosX + ex, m_PosY + ey);
+ //var aabb_min_x = m_PosX - ex;
+ //var aabb_max_x = m_PosX + ex;
+ //var aabb_min_y = m_PosY - ey;
+ //var aabb_max_y = m_PosY + ey;
+ }
+
+ ///
+ /// Unions two boundaries.
+ ///
+ /// First boundary.
+ /// Second boundary.
+ /// New union boundary.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Boundary Union(in Boundary boundary1, in Boundary boundary2)
+ {
+ return new Boundary(
+ boundary1.MinX < boundary2.MinX ? boundary1.MinX : boundary2.MinX,
+ boundary1.MinY < boundary2.MinY ? boundary1.MinY : boundary2.MinY,
+ boundary1.MaxX > boundary2.MaxX ? boundary1.MaxX : boundary2.MaxX,
+ boundary1.MaxY > boundary2.MaxY ? boundary1.MaxY : boundary2.MaxY);
+ }
+
+ ///
+ /// Returns a String which represents the boundary instance.
+ ///
+ /// Value
+ public override string ToString()
+ {
+ return $"MinX:{MinX:F}; MinY:{MinY:F}; MaxX:{MaxX:F}; MaxY:{MaxY:F}; Width: {MaxX - MinX:F}; Height: {MaxY - MinY:F}";
+ }
+
+
+ ///
+ /// Checks to see if the the two boundaries are equal.
+ ///
+ /// First boundary.
+ /// Second boundary.
+ /// True if the two boundaries are equal.
+ public static bool operator ==(in Boundary boundary1, in Boundary boundary2)
+ {
+ return boundary1.Equals(boundary2);
+ }
+
+ ///
+ /// Checks to see if the the two boundaries are equal.
+ ///
+ /// First boundary.
+ /// Second boundary.
+ /// True if the two boundaries are not equal.
+ public static bool operator !=(in Boundary boundary1, in Boundary boundary2)
+ {
+ return boundary1.MinX != boundary2.MaxX ||
+ boundary1.MaxX != boundary2.MinX ||
+ boundary1.MinY != boundary2.MaxY ||
+ boundary1.MaxY != boundary2.MinY;
+ }
+
+ ///
+ /// Checks to see if the other boundary is equal to this boundary.
+ ///
+ /// Other boundary.
+ /// True if the two boundaries are equal.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool Equals(in Boundary other)
+ {
+ return MinX.Equals(other.MinX)
+ && MinY.Equals(other.MinY)
+ && MaxX.Equals(other.MaxX)
+ && MaxY.Equals(other.MaxY);
+ }
+
+
+ ///
+ /// Checks to see if the other object is a boundary and if it is, if it is equal to this boundary.
+ ///
+ /// Other boundary.
+ /// True if the two boundaries are equal.
+ public override bool Equals(object? obj)
+ {
+ return obj is Boundary other && Equals(other);
+ }
+
+ ///
+ /// Gets the hash code of this boundary.
+ ///
+ /// Hash.
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(MinX, MinY, MaxX, MaxY);
+ }
+
+ ///
+ /// Creates a new boundary from a circle at the specified location.
+ ///
+ /// X coordinate of the circle center.
+ /// Y coordinate of the circle center.
+ /// Radius of the circle.
+ /// New boundary.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Boundary FromCircle(float x, float y, float radius)
+ {
+ return new Boundary(
+ x - radius,
+ y - radius,
+ x + radius,
+ y + radius);
+ }
+}
diff --git a/src/DtronixCommon/DtronixCommon.csproj b/src/DtronixCommon/DtronixCommon.csproj
index 13132c4..cef6c6d 100644
--- a/src/DtronixCommon/DtronixCommon.csproj
+++ b/src/DtronixCommon/DtronixCommon.csproj
@@ -2,7 +2,7 @@
net5.0;net6.0
enable
- 0.6.3.0
+ 0.6.4.0
enable
10
Dtronix