< Summary

Information
Class: FixedMathSharp.Bounds.FixedPlane
Assembly: FixedMathSharp
File(s): /home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Primitives/FixedPlane.cs
Line coverage
100%
Covered lines: 59
Uncovered lines: 0
Coverable lines: 59
Total lines: 235
Line coverage: 100%
Branch coverage
100%
Covered branches: 30
Total branches: 30
Branch coverage: 100%
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%
.ctor(...)100%11100%
.ctor(...)100%11100%
DotCoordinate(...)100%11100%
DotNormal(...)100%11100%
NormalizeInPlace()100%11100%
GetNormalized(...)100%22100%
Intersects(...)100%11100%
Intersects(...)100%44100%
Intersects(...)100%44100%
IntersectsBoxLike(...)100%1616100%
Deconstruct(...)100%11100%
op_Equality(...)100%11100%
op_Inequality(...)100%11100%
Equals(...)100%22100%
Equals(...)100%22100%
GetHashCode()100%11100%

File(s)

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Primitives/FixedPlane.cs

#LineLine coverage
 1//=======================================================================
 2// FixedPlane.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2024–present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using MemoryPack;
 9using System;
 10using System.Runtime.CompilerServices;
 11using System.Text.Json.Serialization;
 12
 13namespace FixedMathSharp.Bounds;
 14
 15/// <summary>
 16/// Represents a plane in 3D space using a normal vector and a distance from the origin.
 17/// </summary>
 18[Serializable]
 19[MemoryPackable]
 20public partial struct FixedPlane : IEquatable<FixedPlane>
 21{
 22    #region Fields
 23
 24    /// <summary>
 25    /// The plane normal.
 26    /// </summary>
 27    [JsonInclude]
 28    [MemoryPackOrder(0)]
 29    public Vector3d Normal;
 30
 31    /// <summary>
 32    /// The plane distance component.
 33    /// </summary>
 34    [JsonInclude]
 35    [MemoryPackOrder(1)]
 36    public Fixed64 D;
 37
 38    #endregion
 39
 40    #region Constructors
 41
 42    /// <summary>
 43    /// Initializes a new plane from a normal and distance component.
 44    /// </summary>
 45    [JsonConstructor]
 46    public FixedPlane(Vector3d normal, Fixed64 d)
 47    {
 67148        Normal = normal;
 67149        D = d;
 67150    }
 51
 52    /// <summary>
 53    /// Initializes a new plane from the normal components and distance component.
 54    /// </summary>
 55    public FixedPlane(Fixed64 x, Fixed64 y, Fixed64 z, Fixed64 d)
 28856        : this(new Vector3d(x, y, z), d)
 57    {
 28858    }
 59
 60    /// <summary>
 61    /// Initializes a new plane that contains the specified points.
 62    /// </summary>
 63    public FixedPlane(Vector3d a, Vector3d b, Vector3d c)
 64    {
 165        Vector3d ab = b - a;
 166        Vector3d ac = c - a;
 67
 168        Normal = Vector3d.Cross(ab, ac).NormalizeInPlace();
 169        D = -Vector3d.Dot(Normal, a);
 170    }
 71
 72    /// <summary>
 73    /// Initializes a new plane that contains the specified point with the specified normal.
 74    /// </summary>
 75    public FixedPlane(Vector3d pointOnPlane, Vector3d normal)
 76    {
 177        Normal = normal;
 178        D = -Vector3d.Dot(pointOnPlane, normal);
 179    }
 80
 81    #endregion
 82
 83    #region Methods
 84
 85    /// <summary>
 86    /// Gets the dot product of the specified coordinate and this plane.
 87    /// </summary>
 88    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 89    public Fixed64 DotCoordinate(Vector3d value)
 90    {
 51291        return Vector3d.Dot(Normal, value) + D;
 92    }
 93
 94    /// <summary>
 95    /// Gets the dot product of the specified vector and this plane's normal.
 96    /// </summary>
 97    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 98    public Fixed64 DotNormal(Vector3d value)
 99    {
 34100        return Vector3d.Dot(Normal, value);
 101    }
 102
 103    /// <summary>
 104    /// Normalizes this plane in place.
 105    /// </summary>
 106    public void NormalizeInPlace()
 107    {
 1108        this = GetNormalized(this);
 1109    }
 110
 111    /// <summary>
 112    /// Gets a normalized copy of the specified plane.
 113    /// </summary>
 114    public static FixedPlane GetNormalized(FixedPlane value)
 115    {
 345116        Fixed64 length = value.Normal.Magnitude;
 117
 345118        if (length == Fixed64.Zero)
 1119            throw new ArithmeticException("Cannot normalize a plane with a zero-length normal.");
 120
 344121        Fixed64 factor = Fixed64.One / length;
 344122        return new FixedPlane(value.Normal * factor, value.D * factor);
 123    }
 124
 125    /// <summary>
 126    /// Classifies a bounding box relative to this plane.
 127    /// </summary>
 128    public FixedPlaneIntersectionType Intersects(FixedBoundBox box)
 129    {
 66130        return IntersectsBoxLike(box.Min, box.Max);
 131    }
 132
 133    /// <summary>
 134    /// Classifies a bounding sphere relative to this plane.
 135    /// </summary>
 136    public FixedPlaneIntersectionType Intersects(FixedBoundSphere sphere)
 137    {
 48138        Fixed64 distance = DotCoordinate(sphere.Center);
 139
 48140        if (distance > sphere.Radius)
 3141            return FixedPlaneIntersectionType.Front;
 142
 45143        if (distance < -sphere.Radius)
 24144            return FixedPlaneIntersectionType.Back;
 145
 21146        return FixedPlaneIntersectionType.Intersecting;
 147    }
 148
 149    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 150    internal FixedPlaneIntersectionType Intersects(Vector3d point)
 151    {
 20152        Fixed64 distance = DotCoordinate(point);
 153
 20154        if (distance > Fixed64.Zero)
 10155            return FixedPlaneIntersectionType.Front;
 156
 10157        if (distance < Fixed64.Zero)
 9158            return FixedPlaneIntersectionType.Back;
 159
 1160        return FixedPlaneIntersectionType.Intersecting;
 161    }
 162
 163    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 164    private FixedPlaneIntersectionType IntersectsBoxLike(Vector3d min, Vector3d max)
 165    {
 66166        Vector3d positive = new(
 66167            Normal.X >= Fixed64.Zero ? max.X : min.X,
 66168            Normal.Y >= Fixed64.Zero ? max.Y : min.Y,
 66169            Normal.Z >= Fixed64.Zero ? max.Z : min.Z);
 170
 66171        if (DotCoordinate(positive) < Fixed64.Zero)
 41172            return FixedPlaneIntersectionType.Back;
 173
 25174        Vector3d negative = new(
 25175            Normal.X >= Fixed64.Zero ? min.X : max.X,
 25176            Normal.Y >= Fixed64.Zero ? min.Y : max.Y,
 25177            Normal.Z >= Fixed64.Zero ? min.Z : max.Z);
 178
 25179        if (DotCoordinate(negative) > Fixed64.Zero)
 5180            return FixedPlaneIntersectionType.Front;
 181
 20182        return FixedPlaneIntersectionType.Intersecting;
 183    }
 184
 185    /// <summary>
 186    /// Deconstructs the plane into its normal and distance components.
 187    /// </summary>
 188    public void Deconstruct(out Vector3d normal, out Fixed64 d)
 189    {
 1190        normal = Normal;
 1191        d = D;
 1192    }
 193
 194    #endregion
 195
 196    #region Operators
 197
 198    /// <summary>
 199    /// Determines whether two planes are equal.
 200    /// </summary>
 201    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 44202    public static bool operator ==(FixedPlane left, FixedPlane right) => left.Equals(right);
 203
 204    /// <summary>
 205    /// Determines whether two planes are not equal.
 206    /// </summary>
 207    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1208    public static bool operator !=(FixedPlane left, FixedPlane right) => !left.Equals(right);
 209
 210    #endregion
 211
 212    #region Equality
 213
 214    /// <inheritdoc/>
 215    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2216    public override bool Equals(object? obj) => obj is FixedPlane other && Equals(other);
 217
 218    /// <inheritdoc/>
 219    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 57220    public bool Equals(FixedPlane other) => Normal.Equals(other.Normal) && D.Equals(other.D);
 221
 222    /// <inheritdoc/>
 223    public override int GetHashCode()
 224    {
 225        unchecked
 226        {
 26227            int hash = 17;
 26228            hash = hash * 23 + Normal.GetHashCode();
 26229            hash = hash * 23 + D.GetHashCode();
 26230            return hash;
 231        }
 232    }
 233
 234    #endregion
 235}