< Summary

Information
Class: FixedMathSharp.BoundingArea
Assembly: FixedMathSharp
File(s): /home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Bounds/BoundingArea.cs
Line coverage
100%
Covered lines: 61
Uncovered lines: 0
Coverable lines: 61
Total lines: 273
Line coverage: 100%
Branch coverage
85%
Covered branches: 65
Total branches: 76
Branch coverage: 85.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
.ctor(...)100%11100%
get_Min()100%11100%
get_Max()100%11100%
get_MinX()100%22100%
get_MaxX()100%22100%
get_MinY()100%22100%
get_MaxY()50%22100%
get_MinZ()100%22100%
get_MaxZ()100%22100%
get_Width()100%11100%
get_Height()100%11100%
get_Depth()100%11100%
Contains(...)100%1010100%
Intersects(...)82%5050100%
ProjectPoint(...)100%11100%
op_Equality(...)100%11100%
op_Inequality(...)100%11100%
Equals(...)50%22100%
Equals(...)100%22100%
GetHashCode()100%11100%

File(s)

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Bounds/BoundingArea.cs

#LineLine coverage
 1using MemoryPack;
 2using System;
 3using System.Runtime.CompilerServices;
 4using System.Text.Json.Serialization;
 5
 6namespace FixedMathSharp;
 7
 8/// <summary>
 9/// Represents a lightweight, axis-aligned bounding area with fixed-point precision, optimized for 2D or simplified 3D u
 10/// </summary>
 11/// <remarks>
 12/// The BoundingArea is designed for performance-critical scenarios where only a minimal bounding volume is required.
 13/// It offers fast containment and intersection checks with other bounds but lacks the full feature set of BoundingBox.
 14///
 15/// Use Cases:
 16/// - Efficient spatial queries in 2D or constrained 3D spaces (e.g., terrain maps or collision grids).
 17/// - Simplified bounding volume checks where rotation or complex shape fitting is not needed.
 18/// - Can be used as a broad-phase bounding volume to cull objects before more precise checks with BoundingBox or Boundi
 19/// </remarks>
 20
 21[Serializable]
 22[MemoryPackable]
 23public partial struct BoundingArea : IBound, IEquatable<BoundingArea>
 24{
 25    #region Fields
 26
 27    /// <summary>
 28    /// One of the corner points of the bounding area.
 29    /// </summary>
 30    [JsonInclude]
 31    [MemoryPackOrder(0)]
 32    public Vector3d Corner1;
 33
 34    /// <summary>
 35    /// The opposite corner point of the bounding area.
 36    /// </summary>
 37    [JsonInclude]
 38    [MemoryPackOrder(1)]
 39    public Vector3d Corner2;
 40
 41    #endregion
 42
 43    #region Constructors
 44
 45    /// <summary>
 46    /// Initializes a new instance of the BoundingArea struct with corner coordinates.
 47    /// </summary>
 48    public BoundingArea(Fixed64 c1x, Fixed64 c1y, Fixed64 c1z, Fixed64 c2x, Fixed64 c2y, Fixed64 c2z)
 149    {
 150        Corner1 = new Vector3d(c1x, c1y, c1z);
 151        Corner2 = new Vector3d(c2x, c2y, c2z);
 152    }
 53
 54    /// <summary>
 55    /// Initializes a new instance of the BoundingArea struct with two corner points.
 56    /// </summary>
 57    [JsonConstructor]
 58    public BoundingArea(Vector3d corner1, Vector3d corner2)
 3859    {
 3860        Corner1 = corner1;
 3861        Corner2 = corner2;
 3862    }
 63
 64    #endregion
 65
 66    #region Properties
 67
 68    // Min/Max properties for easy access to boundaries
 69
 70    /// <summary>
 71    /// The minimum corner of the bounding box.
 72    /// </summary>
 73    [JsonIgnore]
 74    [MemoryPackIgnore]
 75    public Vector3d Min
 76    {
 77        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 7178        get => new(MinX, MinY, MinZ);
 79    }
 80
 81    /// <summary>
 82    /// The maximum corner of the bounding box.
 83    /// </summary>
 84    [JsonIgnore]
 85    [MemoryPackIgnore]
 86    public Vector3d Max
 87    {
 88        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 6989        get => new(MaxX, MaxY, MaxZ);
 90    }
 91
 92    [JsonIgnore]
 93    [MemoryPackIgnore]
 94    public Fixed64 MinX
 95    {
 96        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 9197        get => Corner1.x < Corner2.x ? Corner1.x : Corner2.x;
 98    }
 99
 100    [JsonIgnore]
 101    [MemoryPackIgnore]
 102    public Fixed64 MaxX
 103    {
 104        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 89105        get => Corner1.x > Corner2.x ? Corner1.x : Corner2.x;
 106    }
 107
 108    [JsonIgnore]
 109    [MemoryPackIgnore]
 110    public Fixed64 MinY
 111    {
 112        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 84113        get => Corner1.y < Corner2.y ? Corner1.y : Corner2.y;
 114    }
 115
 116    [JsonIgnore]
 117    [MemoryPackIgnore]
 118    public Fixed64 MaxY
 119    {
 120        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 82121        get => Corner1.y > Corner2.y ? Corner1.y : Corner2.y;
 122    }
 123
 124    [JsonIgnore]
 125    [MemoryPackIgnore]
 126    public Fixed64 MinZ
 127    {
 128        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 83129        get => Corner1.z < Corner2.z ? Corner1.z : Corner2.z;
 130    }
 131
 132    [JsonIgnore]
 133    [MemoryPackIgnore]
 134    public Fixed64 MaxZ
 135    {
 136        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 81137        get => Corner1.z > Corner2.z ? Corner1.z : Corner2.z;
 138    }
 139
 140    /// <summary>
 141    /// Calculates the width (X-axis) of the bounding area.
 142    /// </summary>
 143    [JsonIgnore]
 144    [MemoryPackIgnore]
 145    public Fixed64 Width
 146    {
 147        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1148        get => MaxX - MinX;
 149    }
 150
 151    /// <summary>
 152    /// Calculates the height (Y-axis) of the bounding area.
 153    /// </summary>
 154    [JsonIgnore]
 155    [MemoryPackIgnore]
 156    public Fixed64 Height
 157    {
 158        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1159        get => MaxY - MinY;
 160    }
 161
 162    /// <summary>
 163    /// Calculates the depth (Z-axis) of the bounding area.
 164    /// </summary>
 165    [JsonIgnore]
 166    [MemoryPackIgnore]
 167    public Fixed64 Depth
 168    {
 169        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1170        get => MaxZ - MinZ;
 171    }
 172
 173    #endregion
 174
 175    #region Methods (Instance)
 176
 177    /// <summary>
 178    /// Determines if a point is inside the bounding area (including boundaries).
 179    /// </summary>
 180    public bool Contains(Vector3d point)
 18181    {
 182        // Check if the point is within the bounds of the area (including boundaries)
 18183        return point.x >= MinX && point.x <= MaxX
 18184            && point.y >= MinY && point.y <= MaxY
 18185            && point.z >= MinZ && point.z <= MaxZ;
 18186    }
 187
 188    /// <summary>
 189    /// Checks if another IBound intersects with this bounding area.
 190    /// </summary>
 191    /// <remarks>
 192    /// It checks for overlap on all axes. If there is no overlap on any axis, they do not intersect.
 193    /// </remarks>
 194    public bool Intersects(IBound other)
 10195    {
 10196        switch (other)
 197        {
 198            case BoundingBox or BoundingArea:
 8199                {
 8200                    if (Contains(other.Min) && Contains(other.Max))
 1201                        return true;  // Full containment
 202
 203                    // Determine which axis is "flat" (thickness zero)
 7204                    bool flatX = Min.x == Max.x && other.Min.x == other.Max.x;
 7205                    bool flatY = Min.y == Max.y && other.Min.y == other.Max.y;
 7206                    bool flatZ = Min.z == Max.z && other.Min.z == other.Max.z;
 207
 7208                    if (flatZ) // Rectangle in XY
 1209                        return !(Max.x < other.Min.x || Min.x > other.Max.x ||
 1210                                 Max.y < other.Min.y || Min.y > other.Max.y);
 6211                    else if (flatY) // Rectangle in XZ
 1212                        return !(Max.x < other.Min.x || Min.x > other.Max.x ||
 1213                                 Max.z < other.Min.z || Min.z > other.Max.z);
 5214                    else if (flatX) // Rectangle in YZ
 1215                        return !(Max.y < other.Min.y || Min.y > other.Max.y ||
 1216                                 Max.z < other.Min.z || Min.z > other.Max.z);
 217                    else // fallback to 3D volume logic
 4218                        return !(Max.x < other.Min.x || Min.x > other.Max.x ||
 4219                                 Max.y < other.Min.y || Min.y > other.Max.y ||
 4220                                 Max.z < other.Min.z || Min.z > other.Max.z);
 221                }
 222            case BoundingSphere sphere:
 223                // Find the closest point on the area to the sphere's center
 224                // Intersection occurs if the distance from the closest point to the sphere’s center is within the radiu
 1225                return Vector3d.SqrDistance(sphere.Center, this.ProjectPointWithinBounds(sphere.Center)) <= sphere.SqrRa
 226
 1227            default: return false; // Default case for unknown or unsupported types
 228        }
 10229    }
 230
 231    /// <summary>
 232    /// Projects a point onto the bounding box. If the point is outside the box, it returns the closest point on the sur
 233    /// </summary>
 234    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 235    public Vector3d ProjectPoint(Vector3d point)
 1236    {
 1237        return this.ProjectPointWithinBounds(point);
 1238    }
 239
 240    #endregion
 241
 242    #region Operators
 243
 244    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2245    public static bool operator ==(BoundingArea left, BoundingArea right) => left.Equals(right);
 246
 247    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1248    public static bool operator !=(BoundingArea left, BoundingArea right) => !left.Equals(right);
 249
 250    #endregion
 251
 252    #region Equality and HashCode Overrides
 253
 254    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1255    public override bool Equals(object? obj) => obj is BoundingArea other && Equals(other);
 256
 257    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 5258    public bool Equals(BoundingArea other) => Corner1.Equals(other.Corner1) && Corner2.Equals(other.Corner2);
 259
 260    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 261    public override int GetHashCode()
 2262    {
 263        unchecked
 2264        {
 2265            int hash = 17;
 2266            hash = hash * 23 + Corner1.GetHashCode();
 2267            hash = hash * 23 + Corner2.GetHashCode();
 2268            return hash;
 269        }
 2270    }
 271
 272    #endregion
 273}