< Summary

Information
Class: FixedMathSharp.Geometry.CapsulePlaneRayFrame
Assembly: FixedMathSharp
File(s): /home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Wide/FiniteAxis/CapsulePlaneRayFrame.cs
Line coverage
100%
Covered lines: 156
Uncovered lines: 0
Coverable lines: 156
Total lines: 260
Line coverage: 100%
Branch coverage
100%
Covered branches: 84
Total branches: 84
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_UsesWideBanks()100%22100%
get_FieldWords()100%22100%
get_RootWords()100%22100%
get_ValueWords()100%22100%
get_SelectionStorageWords()100%11100%
WithWideParameters()100%22100%
.ctor(...)100%11100%
get_SourceFrame()100%11100%
ForSpherePointRay(...)100%11100%
.ctor(...)100%11100%
ForCapsulePointRay(...)100%11100%
.ctor(...)100%11100%
.ctor(...)100%1616100%
.ctor(...)100%1414100%
GetWorldNormal(...)100%22100%
ComparePoints(...)100%1616100%
ContainsTrianglePoint(...)100%1212100%
GetTriangleEdgeWall(...)100%1414100%
DotWall(...)100%11100%
DotPoint(...)100%11100%
DotPoint(...)100%11100%

File(s)

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Wide/FiniteAxis/CapsulePlaneRayFrame.cs

#LineLine coverage
 1//=======================================================================
 2// CapsulePlaneRayFrame.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 System;
 9
 10namespace FixedMathSharp.Geometry;
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20/// <summary>Canonical finite plane and exact capsule-local coordinates for admitted plane rays.</summary>
 21internal readonly struct CapsulePlaneRayFrame
 22{
 23    internal readonly CapsuleFiniteSectionFrame Finite;
 24    internal readonly WideDirection3d Normal;
 25    internal readonly WideAxis3 AuthoredNormal;
 26    internal readonly Signed832 PlaneConstant, NormalSquared;
 27    private readonly bool _wideParameters;
 1722328    internal bool UsesWideBanks => Finite.ShapeFrame.HasExactScale || _wideParameters;
 29    // Affine event points retain <7680-bit radicands and <12288-bit
 30    // coefficients. Opposite-ray value norms square the coefficients and
 31    // include the point radicand plus <=618 conditioning bits per factor;
 32    // 544 words cover that complete norm. Ordinary banks stay unchanged.
 345033    internal int FieldWords => UsesWideBanks ? 192 : CapsulePlaneRaySelection.FieldWords;
 653434    internal int RootWords => UsesWideBanks ? 120 : CapsulePlaneRaySelection.RootWords;
 501435    internal int ValueWords => UsesWideBanks ? 544 : CapsulePlaneRayValue.PolynomialWords;
 169436    internal int SelectionStorageWords => CapsulePlaneRaySelection.GetStorageWords(FieldWords, RootWords, ValueWords);
 1037    internal CapsulePlaneRayFrame WithWideParameters() => UsesWideBanks ? this : new CapsulePlaneRayFrame(this);
 2438    private CapsulePlaneRayFrame(in CapsulePlaneRayFrame source) { this = source; _wideParameters = true; }
 50839    internal ScaledRigidFrame3d SourceFrame => Finite.ShapeFrame.SourceFrame;
 40
 41    /// <summary>Prepares a explicit sphere plane ray; its rational base point is supplied separately.</summary>
 42    /// <remarks>Only the rational-point accumulator is valid for this frame, not authored plane/edge reconstruction.</r
 43    internal static CapsulePlaneRayFrame ForSpherePointRay(Fixed64 radius, in WideDirection3d direction,
 1544        in Signed832 planeConstant, bool wideParameters = false) => new(radius, direction, planeConstant, wideParameters
 45
 46    private CapsulePlaneRayFrame(Fixed64 radius, in WideDirection3d direction, in Signed832 planeConstant, bool widePara
 47    {
 1548        this = default;
 1549        Finite = new CapsuleFiniteSectionFrame(Vector3d.Zero, FixedQuaternion.Identity,
 1550            Vector3d.Zero, FixedQuaternion.Identity, Fixed64.Zero, radius);
 3051        Normal = direction; PlaneConstant = planeConstant;
 1552        AuthoredNormal = new WideAxis3(Signed320.NarrowValue(direction.X),
 1553            Signed320.NarrowValue(direction.Y), Signed320.NarrowValue(direction.Z));
 1554        NormalSquared = direction.SquaredLength;
 1555        _wideParameters = wideParameters;
 1556    }
 57
 58    /// <summary>Prepares a capsule-local ray chart for exact pretransformed native geometry.</summary>
 59    internal static CapsulePlaneRayFrame ForCapsulePointRay(Fixed64 length, Fixed64 radius,
 60        Signed320 coordinateDenominator, in WideDirection3d direction, in Signed832 planeConstant) =>
 4561        new(length, radius, coordinateDenominator, direction, planeConstant);
 62
 63    private CapsulePlaneRayFrame(Fixed64 length, Fixed64 radius, Signed320 coordinateDenominator,
 64        in WideDirection3d direction, in Signed832 planeConstant)
 65    {
 4566        this = default;
 4567        Finite = new CapsuleFiniteSectionFrame(length, radius, coordinateDenominator);
 13568        Normal = direction; PlaneConstant = planeConstant; NormalSquared = direction.SquaredLength;
 4569        AuthoredNormal = new WideAxis3(Signed320.NarrowValue(direction.X),
 4570            Signed320.NarrowValue(direction.Y), Signed320.NarrowValue(direction.Z));
 4571    }
 72
 73    internal CapsulePlaneRayFrame(FixedTriangle planeTriangle, in CapsuleFiniteSectionFrame finite)
 74    {
 50075        _wideParameters = false;
 50076        Finite = finite;
 50077        planeTriangle.GetExactNormal(out Signed192 nx, out Signed192 ny, out Signed192 nz, out _);
 50078        Span<Signed320> primitive = stackalloc Signed320[3]
 50079        {
 50080            Signed320.ExtendValue(nx), Signed320.ExtendValue(ny), Signed320.ExtendValue(nz)
 50081        };
 98382        if (!nx.IsZero || !ny.IsZero || !nz.IsZero) WideArithmetic.ReduceCommonScale(primitive);
 50083        int sign = primitive[0].Sign != 0 ? primitive[0].Sign
 50084            : primitive[1].Sign != 0 ? primitive[1].Sign : primitive[2].Sign;
 50085        if (sign < 0)
 344386            for (int index = 0; index < 3; index++) primitive[index] = WideArithmetic.Negate(primitive[index]);
 50087        AuthoredNormal = new WideAxis3(primitive[0], primitive[1], primitive[2]);
 50088        WideAxis3 transformed = WideRigidProjection.TransformLocalAxis(finite.ShapeFrame.Basis,
 50089            Signed192.NarrowProven(primitive[0]), Signed192.NarrowProven(primitive[1]), Signed192.NarrowProven(primitive
 150090        primitive[0] = transformed.X; primitive[1] = transformed.Y; primitive[2] = transformed.Z;
 98391        if (!transformed.IsZero) WideArithmetic.ReduceCommonScale(primitive);
 50092        var compactNormal = new WideAxis3(primitive[0], primitive[1], primitive[2]);
 50093        Normal = new WideDirection3d(compactNormal);
 50094        PlaneConstant = Signed832.ExtendValue(WideAxis3.Dot(compactNormal, finite.Transform(planeTriangle.A)));
 50095        NormalSquared = Signed832.ExtendValue(WideAxis3.Dot(compactNormal, compactNormal));
 50096    }
 97
 98    internal CapsulePlaneRayFrame(FixedTriangle planeTriangle, in ScaledRigidFrame3d sourceFrame,
 99        in CapsuleFiniteSectionFrame finite)
 100    {
 1068101        if (sourceFrame.IsRigid)
 102        {
 4103            this = new CapsulePlaneRayFrame(planeTriangle, finite);
 4104            return;
 105        }
 1064106        _wideParameters = false;
 1064107        Finite = finite;
 1064108        WideDirection3d first = WideDirection3d.GetLocalEdge(sourceFrame, planeTriangle.A, planeTriangle.B);
 1064109        WideDirection3d second = WideDirection3d.GetLocalEdge(sourceFrame, planeTriangle.A, planeTriangle.C);
 1064110        WideDirection3d cross = WideDirection3d.Cross(first, second);
 1064111        Span<Signed320> primitive = stackalloc Signed320[3]
 1064112        {
 1064113            Signed320.NarrowValue(cross.X), Signed320.NarrowValue(cross.Y), Signed320.NarrowValue(cross.Z)
 1064114        };
 2126115        if (!cross.IsZero) WideArithmetic.ReduceCommonScale(primitive);
 1064116        int sign = primitive[0].Sign != 0 ? primitive[0].Sign
 1064117            : primitive[1].Sign != 0 ? primitive[1].Sign : primitive[2].Sign;
 1064118        if (sign < 0)
 6424119            for (int index = 0; index < 3; index++) primitive[index] = WideArithmetic.Negate(primitive[index]);
 1064120        AuthoredNormal = new WideAxis3(primitive[0], primitive[1], primitive[2]);
 1064121        WideDirection3d transformed = new WideDirection3d(AuthoredNormal).Transform(finite.ShapeFrame.Basis);
 1064122        Span<Signed576> reduced = stackalloc Signed576[3] { transformed.X, transformed.Y, transformed.Z };
 2126123        if (!transformed.IsZero) WideArithmetic.ReduceCommonScale(reduced);
 1064124        Normal = new WideDirection3d(reduced[0], reduced[1], reduced[2]);
 1064125        PlaneConstant = WideDirection3d.Dot(Normal, finite.Transform(planeTriangle.A));
 1064126        NormalSquared = Normal.SquaredLength;
 1064127    }
 128
 129    internal Vector3d GetWorldNormal(FixedQuaternion authoredRotation)
 130    {
 191131        if (Finite.ShapeFrame.HasExactScale)
 4132            return new WideDirection3d(AuthoredNormal).Transform(SourceFrame.GeometryBasis).GetNormal(false);
 187133        WideAxis3 normal = WideRigidProjection.TransformLocalAxis(new WideRationalBasis3d(authoredRotation),
 187134            Signed192.NarrowProven(AuthoredNormal.X), Signed192.NarrowProven(AuthoredNormal.Y),
 187135            Signed192.NarrowProven(AuthoredNormal.Z));
 187136        return WideNormalization.GetNormalized(normal.X, normal.Y, normal.Z);
 137    }
 138
 139    /// <summary>Compares exact points in the authored frame; the common translation cancels.</summary>
 140    internal int ComparePoints(scoped ContactQuadratic x, scoped ContactQuadratic y, scoped ContactQuadratic z,
 141        scoped ContactQuadratic d, scoped ReadOnlySpan<ulong> root, scoped ContactQuadratic otherX,
 142        scoped ContactQuadratic otherY, scoped ContactQuadratic otherZ, scoped ContactQuadratic otherD,
 143        scoped ReadOnlySpan<ulong> otherRoot)
 144    {
 145        // Basis covectors add at most 130 bits and two carries; retained bank
 146        // capacity does not determine the width of the actual point products.
 611147        int words = Math.Max(9, Math.Max(Math.Max(ContactQuadratic.ActiveWords(x),
 611148            Math.Max(ContactQuadratic.ActiveWords(y), ContactQuadratic.ActiveWords(z))),
 611149            Math.Max(ContactQuadratic.ActiveWords(otherX), Math.Max(ContactQuadratic.ActiveWords(otherY),
 611150                ContactQuadratic.ActiveWords(otherZ)))) + 3);
 1222151        Span<ulong> values = stackalloc ulong[6 * words]; Span<int> signs = stackalloc int[6];
 611152        ContactQuadratic first = ContactQuadratic.At(values, signs, 0, words);
 611153        ContactQuadratic second = ContactQuadratic.At(values, signs, 1, words);
 611154        ContactQuadratic term = ContactQuadratic.At(values, signs, 2, words);
 611155        WideRationalBasis3d basis = Finite.ShapeFrame.Basis;
 4582156        for (int axis = 0; axis < 3; axis++)
 157        {
 1748158            Signed192 bx = axis == 0 ? basis.Xx : axis == 1 ? basis.Yx : basis.Zx;
 1748159            Signed192 by = axis == 0 ? basis.Xy : axis == 1 ? basis.Yy : basis.Zy;
 1748160            Signed192 bz = axis == 0 ? basis.Xz : axis == 1 ? basis.Yz : basis.Zz;
 1748161            DotPoint(Signed576.ExtendValue(Signed320.ExtendValue(bx)),
 1748162                Signed576.ExtendValue(Signed320.ExtendValue(by)), Signed576.ExtendValue(Signed320.ExtendValue(bz)),
 1748163                x, y, z, first, term);
 1748164            DotPoint(Signed576.ExtendValue(Signed320.ExtendValue(bx)),
 1748165                Signed576.ExtendValue(Signed320.ExtendValue(by)), Signed576.ExtendValue(Signed320.ExtendValue(bz)),
 1748166                otherX, otherY, otherZ, second, term);
 1748167            int comparison = ContactQuadratic.CompareRatios(first, d, root, second, otherD, otherRoot);
 1816168            if (comparison != 0) return comparison;
 169        }
 543170        return 0;
 171    }
 172
 173    /// <summary>Tests an exact homogeneous capsule-local point against the closed finite triangle.</summary>
 174    internal bool ContainsTrianglePoint(FixedTriangle triangle, ContactQuadratic x, ContactQuadratic y,
 175        ContactQuadratic z, ContactQuadratic denominator, ReadOnlySpan<ulong> root)
 176    {
 695177        if (NormalSquared.IsZero || denominator.Sign(root) <= 0) return false;
 178        // Plane/wall products add at most 526 bits to a point coefficient.
 179        // Input banks may be larger than this owner's rational witness bank.
 689180        int words = Math.Max(Math.Max(ContactQuadratic.ActiveWords(x), ContactQuadratic.ActiveWords(y)),
 689181            Math.Max(ContactQuadratic.ActiveWords(z), ContactQuadratic.ActiveWords(denominator)))
 689182            + (Finite.ShapeFrame.HasExactScale ? 13 : 9);
 689183        Span<ulong> values = stackalloc ulong[4 * words];
 689184        Span<int> signs = stackalloc int[4];
 689185        ContactQuadratic value = ContactQuadratic.At(values, signs, 0, words);
 689186        ContactQuadratic term = ContactQuadratic.At(values, signs, 1, words);
 689187        DotPoint(Normal.X, Normal.Y, Normal.Z,
 689188            x, y, z, value, term);
 1378189        ContactQuadratic.Scale(denominator, PlaneConstant, term); value.Add(term, -1);
 695190        if (value.Sign(root) != 0) return false;
 4290191        for (int edge = 0; edge < 3; edge++)
 192        {
 1753193            GetTriangleEdgeWall(triangle, edge, out Signed832 wx, out Signed832 wy, out Signed832 wz, out Signed832 offs
 1753194            DotPoint(wx, wy, wz, x, y, z, value, term);
 3506195            ContactQuadratic.Scale(denominator, offset, term); value.Add(term, -1);
 2044196            if (value.Sign(root) < 0) return false;
 197        }
 392198        return true;
 199    }
 200
 201    internal void GetTriangleEdgeWall(FixedTriangle triangle, int index,
 202        out Signed832 x, out Signed832 y, out Signed832 z, out Signed832 offset)
 203    {
 1822204        FixedSegment edge = triangle.GetEdge(index);
 1822205        if (Finite.ShapeFrame.HasExactScale)
 206        {
 504207            WideDirection3d deltaExact = WideDirection3d.GetLocalEdge(SourceFrame, edge.Start, edge.End);
 504208            WideDirection3d wallExact = WideDirection3d.Cross(new WideDirection3d(AuthoredNormal), deltaExact)
 504209                .Transform(Finite.ShapeFrame.Basis);
 1008210            x = Signed832.ExtendValue(wallExact.X); y = Signed832.ExtendValue(wallExact.Y);
 504211            z = Signed832.ExtendValue(wallExact.Z);
 504212            offset = WideDirection3d.Dot(wallExact, Finite.Transform(edge.Start));
 504213            WideAxis3 oppositeExact = Finite.Transform(index == 0 ? triangle.C : index == 1 ? triangle.A : triangle.B);
 504214            if (WideArithmetic.SubtractSigned832(WideDirection3d.Dot(wallExact, oppositeExact), offset).Sign < 0)
 215            {
 422216                x = WideArithmetic.SubtractSigned832(default, x); y = WideArithmetic.SubtractSigned832(default, y);
 422217                z = WideArithmetic.SubtractSigned832(default, z); offset = WideArithmetic.SubtractSigned832(default, off
 218            }
 504219            return;
 220        }
 1318221        WideAxis3 delta = new(
 1318222            Signed320.ExtendValue(WideArithmetic.SubtractSigned192(Signed192.Raw(edge.End.X), Signed192.Raw(edge.Start.X
 1318223            Signed320.ExtendValue(WideArithmetic.SubtractSigned192(Signed192.Raw(edge.End.Y), Signed192.Raw(edge.Start.Y
 1318224            Signed320.ExtendValue(WideArithmetic.SubtractSigned192(Signed192.Raw(edge.End.Z), Signed192.Raw(edge.Start.Z
 225        // Form the authored wall before transforming it: 130-bit normal,
 226        // 65-bit edge, 130-bit relative basis keep the wall below 327 bits.
 1318227        WideAxis3 wall = WideAxis3.Cross(AuthoredNormal, delta);
 1318228        WideRigidProjection.TransformLocalAxis(Finite.ShapeFrame.Basis, wall, out Signed576 wx, out Signed576 wy, out Si
 3954229        x = Signed832.ExtendValue(wx); y = Signed832.ExtendValue(wy); z = Signed832.ExtendValue(wz);
 1318230        offset = Signed832.ExtendValue(DotWall(wx, wy, wz, Finite.Transform(edge.Start)));
 1318231        WideAxis3 opposite = Finite.Transform(index == 0 ? triangle.C : index == 1 ? triangle.A : triangle.B);
 1318232        if (WideArithmetic.SubtractSigned832(Signed832.ExtendValue(DotWall(wx, wy, wz, opposite)), offset).Sign < 0)
 233        {
 1618234            x = WideArithmetic.SubtractSigned832(default, x); y = WideArithmetic.SubtractSigned832(default, y);
 1618235            z = WideArithmetic.SubtractSigned832(default, z); offset = WideArithmetic.SubtractSigned832(default, offset)
 236        }
 1318237    }
 238
 239    private static Signed576 DotWall(Signed576 x, Signed576 y, Signed576 z, WideAxis3 point) =>
 2636240        Signed576.NarrowValue(WideArithmetic.AddSigned704(
 2636241            WideArithmetic.AddSigned704(WideArithmetic.MultiplySigned576ToSigned704(x, point.X),
 2636242                WideArithmetic.MultiplySigned576ToSigned704(y, point.Y)),
 2636243            WideArithmetic.MultiplySigned576ToSigned704(z, point.Z)));
 244
 245    private static void DotPoint(Signed576 wx, Signed576 wy, Signed576 wz, ContactQuadratic x,
 246        ContactQuadratic y, ContactQuadratic z, ContactQuadratic result, ContactQuadratic term)
 247    {
 4185248        ContactQuadratic.Scale(x, wx, result);
 8370249        ContactQuadratic.Scale(y, wy, term); result.Add(term);
 8370250        ContactQuadratic.Scale(z, wz, term); result.Add(term);
 4185251    }
 252
 253    private static void DotPoint(Signed832 wx, Signed832 wy, Signed832 wz, ContactQuadratic x,
 254        ContactQuadratic y, ContactQuadratic z, ContactQuadratic result, ContactQuadratic term)
 255    {
 1753256        ContactQuadratic.Scale(x, wx, result);
 3506257        ContactQuadratic.Scale(y, wy, term); result.Add(term);
 3506258        ContactQuadratic.Scale(z, wz, term); result.Add(term);
 1753259    }
 260}

Methods/Properties

get_UsesWideBanks()
get_FieldWords()
get_RootWords()
get_ValueWords()
get_SelectionStorageWords()
WithWideParameters()
.ctor(FixedMathSharp.Geometry.CapsulePlaneRayFrame&)
get_SourceFrame()
ForSpherePointRay(FixedMathSharp.Fixed64,FixedMathSharp.Geometry.WideDirection3d&,FixedMathSharp.Signed832&,System.Boolean)
.ctor(FixedMathSharp.Fixed64,FixedMathSharp.Geometry.WideDirection3d&,FixedMathSharp.Signed832&,System.Boolean)
ForCapsulePointRay(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Signed320,FixedMathSharp.Geometry.WideDirection3d&,FixedMathSharp.Signed832&)
.ctor(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Signed320,FixedMathSharp.Geometry.WideDirection3d&,FixedMathSharp.Signed832&)
.ctor(FixedMathSharp.Geometry.FixedTriangle,FixedMathSharp.Geometry.CapsuleFiniteSectionFrame&)
.ctor(FixedMathSharp.Geometry.FixedTriangle,FixedMathSharp.Geometry.ScaledRigidFrame3d&,FixedMathSharp.Geometry.CapsuleFiniteSectionFrame&)
GetWorldNormal(FixedMathSharp.FixedQuaternion)
ComparePoints(FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,System.ReadOnlySpan`1<System.UInt64>,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,System.ReadOnlySpan`1<System.UInt64>)
ContainsTrianglePoint(FixedMathSharp.Geometry.FixedTriangle,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,System.ReadOnlySpan`1<System.UInt64>)
GetTriangleEdgeWall(FixedMathSharp.Geometry.FixedTriangle,System.Int32,FixedMathSharp.Signed832&,FixedMathSharp.Signed832&,FixedMathSharp.Signed832&,FixedMathSharp.Signed832&)
DotWall(FixedMathSharp.Signed576,FixedMathSharp.Signed576,FixedMathSharp.Signed576,FixedMathSharp.Geometry.WideAxis3)
DotPoint(FixedMathSharp.Signed576,FixedMathSharp.Signed576,FixedMathSharp.Signed576,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic)
DotPoint(FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic)