< Summary

Line coverage
100%
Covered lines: 233
Uncovered lines: 0
Coverable lines: 233
Total lines: 424
Line coverage: 100%
Branch coverage
100%
Covered branches: 164
Total branches: 164
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// FiniteSlabSectionFrame.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/// <summary>Exact closed admission for a flat-capped circle or Z-axis stadium extrusion.</summary>
 13/// <content>Owns finite point, segment, and triangle section admission in one exact rigid frame.</content>
 14internal readonly partial struct FiniteSlabSectionFrame
 15{
 16    // The planar capsule is the Y-core capsule kernel evaluated at (X,Z,0).
 17    // Full endpoint disks and the central rectangle have exactly the stadium
 18    // union; extra hemisphere clipping would only add redundant constraints.
 19    private readonly CapsuleFiniteSectionFrame _radial;
 20    private readonly Signed320 _cap;
 101721    private ScaledRigidFrame3d SourceFrame => _radial.ShapeFrame.SourceFrame;
 4515522    internal CapsuleFiniteSectionFrame RadialFrame => _radial;
 234323    internal Signed320 Cap => _cap;
 670224    internal WideAxis3 Transform(Vector3d point) => _radial.Transform(point);
 871325    internal int PointWords => _radial.ShapeFrame.HasExactScale ? FiniteSectionPoint.AffineWords : FiniteSectionPoint.Wo
 53626    internal int RootWords => _radial.ShapeFrame.HasExactScale ? FiniteSectionPoint.AffineRootWords : FiniteSectionPoint
 27
 28    /// <summary>Prepares an exact primitive-local circle extrusion for pretransformed source coordinates.</summary>
 29    internal FiniteSlabSectionFrame(Fixed64 height, Fixed64 radius, Signed320 coordinateDenominator)
 30    {
 3731        _radial = new CapsuleFiniteSectionFrame(Fixed64.Zero, radius, coordinateDenominator);
 3732        _cap = Signed320.NarrowValue(WideArithmetic.MultiplySigned320(coordinateDenominator,
 3733            Signed320.ExtendValue(Signed192.Raw(height))));
 3734    }
 35
 36    internal FiniteSlabSectionFrame(Vector3d origin, FixedQuaternion rotation,
 37        Vector3d center, FixedQuaternion slabRotation, Fixed64 length, Fixed64 radius, Fixed64 halfThickness, bool fullH
 38    {
 52739        if (halfThickness <= Fixed64.Zero) throw new ArgumentOutOfRangeException(nameof(halfThickness));
 52340        _radial = new CapsuleFiniteSectionFrame(origin, rotation, center, slabRotation, length, radius);
 41        // Transformed coordinates carry 2D, so an authored full height
 42        // supplies the exact cap directly, including an odd raw half-height.
 52343        Signed192 height = fullHeight ? Signed192.Raw(halfThickness)
 52344            : WideArithmetic.AddSigned192(Signed192.Raw(halfThickness), Signed192.Raw(halfThickness));
 52345        _cap = WideArithmetic.MultiplySigned192(height, _radial.ShapeFrame.Denominator);
 52346    }
 47
 48    internal FiniteSlabSectionFrame(in ScaledRigidFrame3d sourceFrame,
 49        Vector3d center, FixedQuaternion slabRotation, Fixed64 length, Fixed64 radius, Fixed64 halfThickness, bool fullH
 50    {
 18351        if (sourceFrame.IsRigid)
 52        {
 1653            this = new FiniteSlabSectionFrame(sourceFrame.RigidOrigin, sourceFrame.Rotation,
 1654                center, slabRotation, length, radius, halfThickness, fullHeight);
 1655            return;
 56        }
 16757        if (halfThickness <= Fixed64.Zero || halfThickness > (Fixed64)(fullHeight ? 8192 : 4096))
 458            throw new ArgumentOutOfRangeException(nameof(halfThickness));
 16359        _radial = new CapsuleFiniteSectionFrame(sourceFrame, center, slabRotation, length, radius);
 16360        Signed192 height = fullHeight ? Signed192.Raw(halfThickness)
 16361            : WideArithmetic.AddSigned192(Signed192.Raw(halfThickness), Signed192.Raw(halfThickness));
 16362        _cap = Signed320.NarrowValue(WideArithmetic.MultiplySigned320(_radial.ShapeFrame.CoordinateDenominator, height))
 16363    }
 64
 65    internal bool ContainsPoint(Vector3d point)
 66    {
 2867        WideAxis3 p = _radial.Transform(point);
 2868        return WideArithmetic.AddSigned320(p.Y, _cap).Sign >= 0
 2869            && WideArithmetic.SubtractSigned320(p.Y, _cap).Sign <= 0
 2870            && _radial.ContainsTransformedPoint(Radial(p));
 71    }
 72
 73    internal bool ContainsPoint(Vector3d point, ReadOnlySpan<Vector2d> prismOffsets)
 74    {
 3375        if (prismOffsets.IsEmpty) return ContainsPoint(point);
 2976        WideAxis3 p = Transform(point);
 2977        if (WideArithmetic.AddSigned320(p.Y, _cap).Sign < 0
 3478            || WideArithmetic.SubtractSigned320(p.Y, _cap).Sign > 0) return false;
 2479        int winding = GetPrismWinding(prismOffsets);
 20280        for (int edge = 0; edge < prismOffsets.Length; edge++)
 8581            if (PrismWall(p, prismOffsets[edge], prismOffsets[(edge + 1) % prismOffsets.Length]).Sign * winding < 0)
 882                return false;
 1683        return true;
 84    }
 85
 86    internal bool IntersectsSegment(FixedSegment segment, ReadOnlySpan<Vector2d> prismOffsets)
 87    {
 741788        if (prismOffsets.IsEmpty) return IntersectsSegment(segment);
 20289        Span<ulong> values = stackalloc ulong[4 * PointWords]; Span<int> signs = stackalloc int[4];
 20290        Span<ulong> root = stackalloc ulong[RootWords]; root.Clear();
 10191        return TryGetPrismSegmentParameter(segment, prismOffsets,
 10192            ContactQuadratic.At(values, signs, 0, PointWords),
 10193            ContactQuadratic.At(values, signs, 1, PointWords), root);
 94    }
 95
 96    /// <summary>Tests an exact pretransformed subsegment in the existing radial and height intervals.</summary>
 97    internal bool IntersectsTransformedSegment(WideAxis3 start, WideAxis3 end, in RationalSegmentInterval clip)
 98    {
 8799        WideAxis3 delta = Difference(end, start);
 312100        for (int primitive = 0; primitive < (_radial.Length == Fixed64.Zero ? 1 : 3); primitive++)
 117101            if (TryGetPrimitive(start, delta, primitive, out Signed832 a, out Signed832 b, out Signed832 c,
 117102                    out var ln, out var ld, out var un, out var ud)
 165103                && CapsuleFiniteSectionFrame.IntersectsQuadratic(a, b, c, ln, ld, un, ud, clip)) return true;
 39104        return false;
 105    }
 106
 107    /// <summary>Tests a retained exact subsegment without rounding either cut endpoint.</summary>
 108    internal bool IntersectsSegment(FixedSegment segment, in RationalSegmentInterval clip) =>
 48109        IntersectsTransformedSegment(Transform(segment.Start), Transform(segment.End), clip);
 110
 111    internal bool TryGetFirstSegmentParameter(FixedSegment segment, ReadOnlySpan<Vector2d> prismOffsets,
 1289112        ContactQuadratic numerator, ContactQuadratic denominator, Span<ulong> root) => prismOffsets.IsEmpty
 1289113        ? TryGetFirstSegmentParameter(segment, numerator, denominator, root)
 1289114        : TryGetPrismSegmentParameter(segment, prismOffsets, numerator, denominator, root);
 115
 116    /// <summary>Retains the first finite parameter admitted by the slab's projected footprint, without height clipping.
 117    internal bool TryGetFirstProjectedSegmentParameter(FixedSegment segment, ReadOnlySpan<Vector2d> prismOffsets,
 197118        ContactQuadratic numerator, ContactQuadratic denominator, Span<ulong> root) => prismOffsets.IsEmpty
 197119        ? TryGetFirstSegmentParameter(segment, numerator, denominator, root, includeHeight: false)
 197120        : TryGetPrismSegmentParameter(segment, prismOffsets, numerator, denominator, root, includeHeight: false);
 121
 122    private bool TryGetPrismSegmentParameter(FixedSegment segment, ReadOnlySpan<Vector2d> offsets,
 123        ContactQuadratic numerator, ContactQuadratic denominator, Span<ulong> root, bool includeHeight = true)
 124    {
 3480125        numerator.Clear(); denominator.Set(Signed576.ExtendValue(Signed320.ExtendValue(Signed192.Signed(1)))); root.Clea
 2320126        Span<ulong> values = stackalloc ulong[8 * PointWords]; Span<int> signs = stackalloc int[8];
 1160127        ContactQuadratic upperN = ContactQuadratic.At(values, signs, 0, PointWords),
 1160128            upperD = ContactQuadratic.At(values, signs, 1, PointWords),
 1160129            n = ContactQuadratic.At(values, signs, 2, PointWords),
 1160130            d = ContactQuadratic.At(values, signs, 3, PointWords);
 2320131        upperN.Set(Signed576.ExtendValue(Signed320.ExtendValue(Signed192.Signed(1)))); upperN.CopyTo(upperD);
 2320132        WideAxis3 first = Transform(segment.Start), last = Transform(segment.End);
 1160133        int winding = GetPrismWinding(offsets);
 14432134        for (int wall = includeHeight ? -2 : 0; wall < offsets.Length; wall++)
 135        {
 136            Signed576 a, b;
 6231137            if (wall == -2)
 138            {
 972139                a = Signed576.ExtendValue(WideArithmetic.AddSigned320(first.Y, _cap));
 972140                b = Signed576.ExtendValue(WideArithmetic.AddSigned320(last.Y, _cap));
 141            }
 5259142            else if (wall == -1)
 143            {
 972144                a = Signed576.ExtendValue(WideArithmetic.SubtractSigned320(_cap, first.Y));
 972145                b = Signed576.ExtendValue(WideArithmetic.SubtractSigned320(_cap, last.Y));
 146            }
 147            else
 148            {
 8574149                Vector2d start = offsets[wall], end = offsets[(wall + 1) % offsets.Length];
 8574150                a = PrismWall(first, start, end); b = PrismWall(last, start, end);
 4423151                if (winding < 0) { a = WideArithmetic.SubtractSigned576(default, a); b = WideArithmetic.SubtractSigned57
 152            }
 6231153            Signed576 velocity = WideArithmetic.SubtractSigned576(b, a);
 9976154            if (velocity.IsZero) { if (a.Sign < 0) return false; continue; }
 2516155            if (velocity.Sign > 0)
 156            {
 2524157                n.Set(WideArithmetic.SubtractSigned576(default, a)); d.Set(velocity);
 1262158                if (ContactQuadratic.CompareRatios(n, d, root, numerator, denominator, root) > 0)
 786159                { n.CopyTo(numerator); d.CopyTo(denominator); }
 160            }
 161            else
 162            {
 2508163                n.Set(a); d.Set(WideArithmetic.SubtractSigned576(default, velocity));
 1254164                if (ContactQuadratic.CompareRatios(n, d, root, upperN, upperD, root) < 0)
 782165                { n.CopyTo(upperN); d.CopyTo(upperD); }
 166            }
 2661167            if (ContactQuadratic.CompareRatios(numerator, denominator, root, upperN, upperD, root) > 0) return false;
 168        }
 985169        return true;
 170    }
 171
 172    private Signed576 PrismWall(WideAxis3 point, Vector2d start, Vector2d end)
 173    {
 8659174        Signed320 scale = WideArithmetic.AddSigned320(_radial.ShapeFrame.CoordinateDenominator, _radial.ShapeFrame.Coord
 8659175        Signed320 x = WideArithmetic.SubtractSigned320(point.X, Signed320.NarrowValue(WideArithmetic.MultiplySigned320(s
 8659176        Signed320 z = WideArithmetic.SubtractSigned320(point.Z, Signed320.NarrowValue(WideArithmetic.MultiplySigned320(s
 8659177        Signed320 ex = Signed320.ExtendValue(WideArithmetic.SubtractSigned192(Signed192.Raw(end.X), Signed192.Raw(start.
 8659178        Signed320 ez = Signed320.ExtendValue(WideArithmetic.SubtractSigned192(Signed192.Raw(end.Y), Signed192.Raw(start.
 8659179        return WideArithmetic.SubtractSigned576(WideArithmetic.MultiplySigned320(ex, z), WideArithmetic.MultiplySigned32
 180    }
 181
 182    internal static int GetPrismWinding(ReadOnlySpan<Vector2d> offsets)
 183    {
 5604184        if (offsets.Length < 3) throw new ArgumentException("A convex prism requires at least three offsets.", nameof(of
 5598185        Vector2d a = offsets[0];
 11852186        for (int index = 1; index + 1 < offsets.Length; index++)
 187        {
 5923188            Signed192 x = WideArithmetic.SubtractSigned192(Signed192.Raw(offsets[index].X), Signed192.Raw(a.X));
 5923189            Signed192 z = WideArithmetic.SubtractSigned192(Signed192.Raw(offsets[index].Y), Signed192.Raw(a.Y));
 5923190            Signed192 y = WideArithmetic.SubtractSigned192(Signed192.Raw(offsets[index + 1].X), Signed192.Raw(a.X));
 5923191            Signed192 w = WideArithmetic.SubtractSigned192(Signed192.Raw(offsets[index + 1].Y), Signed192.Raw(a.Y));
 5923192            int sign = WideArithmetic.SubtractSigned320(WideArithmetic.MultiplySigned192(x, w), WideArithmetic.MultiplyS
 11518193            if (sign != 0) return sign;
 194        }
 3195        throw new ArgumentException("The convex prism offsets must span an area.", nameof(offsets));
 196    }
 197
 198    internal bool IntersectsSegment(FixedSegment segment)
 199    {
 7344200        WideAxis3 start = _radial.Transform(segment.Start), delta = Difference(_radial.Transform(segment.End), start);
 27406201        for (int primitive = 0; primitive < (_radial.Length == Fixed64.Zero ? 1 : 3); primitive++)
 10345202            if (TryGetPrimitive(start, delta, primitive, out Signed832 a, out Signed832 b, out Signed832 c,
 10345203                    out Signed320 ln, out Signed320 ld, out Signed320 un, out Signed320 ud)
 10659204                && CapsuleFiniteSectionFrame.IntersectsQuadratic(a, b, c, ln, ld, un, ud)) return true;
 3358205        return false;
 206    }
 207
 208    internal bool TryGetFirstSegmentParameter(FixedSegment segment,
 209        ContactQuadratic numerator, ContactQuadratic denominator, Span<ulong> root)
 426210        => TryGetFirstSegmentParameter(segment, numerator, denominator, root, includeHeight: true);
 211
 212    private bool TryGetFirstSegmentParameter(FixedSegment segment,
 213        ContactQuadratic numerator, ContactQuadratic denominator, Span<ulong> root, bool includeHeight)
 214    {
 1305215        numerator.Clear(); denominator.Clear(); root.Clear();
 870216        WideAxis3 start = _radial.Transform(segment.Start), delta = Difference(_radial.Transform(segment.End), start);
 870217        Span<ulong> values = stackalloc ulong[10 * PointWords]; Span<int> signs = stackalloc int[10];
 435218        Span<ulong> candidateRoot = stackalloc ulong[RootWords];
 435219        ContactQuadratic qa = ContactQuadratic.At(values, signs, 0, PointWords),
 435220            qb = ContactQuadratic.At(values, signs, 1, PointWords),
 435221            qc = ContactQuadratic.At(values, signs, 2, PointWords),
 435222            n = ContactQuadratic.At(values, signs, 3, PointWords),
 435223            d = ContactQuadratic.At(values, signs, 4, PointWords);
 435224        bool found = false;
 3268225        for (int primitive = 0; primitive < (_radial.Length == Fixed64.Zero ? 1 : 3); primitive++)
 226        {
 1199227            if (!TryGetPrimitive(start, delta, primitive, out Signed832 a, out Signed832 b, out Signed832 c,
 1199228                    out Signed320 ln, out Signed320 ld, out Signed320 un, out Signed320 ud, includeHeight)
 1199229                || !CapsuleFiniteSectionFrame.IntersectsQuadratic(a, b, c, ln, ld, un, ud)) continue;
 1806230            n.Clear(); d.Clear(); candidateRoot.Clear();
 602231            SetFirstQuadraticParameter(a, b, c, ln, ld, qa, qb, qc, n, d, candidateRoot);
 602232            if (!found || ContactQuadratic.CompareRatios(n, d, candidateRoot, numerator, denominator, root) < 0)
 233            {
 1712234                n.CopyTo(numerator); d.CopyTo(denominator); candidateRoot.CopyTo(root); found = true;
 235            }
 236        }
 435237        return found;
 238    }
 239
 240    private bool TryGetPrimitive(WideAxis3 start, WideAxis3 delta, int primitive,
 241        out Signed832 a, out Signed832 b, out Signed832 c,
 242        out Signed320 ln, out Signed320 ld, out Signed320 un, out Signed320 ud, bool includeHeight = true)
 243    {
 11661244        if (!_radial.TryGetPrimitiveWide(Radial(start), Radial(delta), primitive, out a, out b, out c,
 12998245                out ln, out ld, out un, out ud)) return false;
 10333246        if (!includeHeight) return true;
 41260247        Signed320 rn = ln, rd = ld, sn = un, sd = ud;
 10315248        if (!CapsuleFiniteSectionFrame.TryGetCenteredAxisInterval(start.Y, delta.Y, _cap, out ln, out ld, out un, out ud
 6266249            return false;
 250        // Doubled normalized-frame coordinates and differences are <198 bits.
 251        // Interval cross products fit 398 bits; radial coefficients <400,
 252        // discriminants <801. Flat clipping adds no polynomial factors, so
 253        // the existing ten-limb point and seventeen-limb root banks suffice.
 4647254        if (Compare(rn, rd, ln, ld) > 0) { ln = rn; ld = rd; }
 4661255        if (Compare(sn, sd, un, ud) < 0) { un = sn; ud = sd; }
 4049256        return Compare(ln, ld, un, ud) <= 0;
 257    }
 258
 259    private static int Compare(Signed320 n, Signed320 d, Signed320 otherN, Signed320 otherD) =>
 12147260        WideArithmetic.SubtractSigned832(WideArithmetic.MultiplySigned576ToSigned832(Signed576.ExtendValue(n), otherD), 
 261
 262    private static void SetFirstQuadraticParameter(Signed832 a, Signed832 b, Signed832 c,
 263        Signed320 lowerN, Signed320 lowerD, ContactQuadratic qa, ContactQuadratic qb, ContactQuadratic qc,
 264        ContactQuadratic numerator, ContactQuadratic denominator, Span<ulong> root)
 265    {
 602266        if (WideFiniteConeIntersection.GetPolynomialSignAtRationalParameter(a, b, c, lowerN, lowerD) <= 0)
 267        {
 972268            numerator.Set(Signed576.ExtendValue(lowerN)); denominator.Set(Signed576.ExtendValue(lowerD));
 486269            return;
 270        }
 348271        qa.Set(a); qb.Set(b); qc.Set(c);
 116272        bool retained = ContactQuadratic.TryGetParameter(qa, qb, qc, -1, root, numerator, denominator);
 125273        if (!retained) retained = ContactQuadratic.TryGetParameter(qa, qb, qc, 1, root, numerator, denominator);
 274        System.Diagnostics.Debug.Assert(retained);
 116275    }
 276
 23342277    private static WideAxis3 Radial(WideAxis3 point) => new(point.X, point.Z, default);
 4194278    private static WideAxis3 Difference(WideAxis3 end, WideAxis3 start) => new(
 4194279        WideArithmetic.SubtractSigned320(end.X, start.X), WideArithmetic.SubtractSigned320(end.Y, start.Y),
 4194280        WideArithmetic.SubtractSigned320(end.Z, start.Z));
 281}

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Wide/FiniteAxis/FiniteSlabSectionFrame.Triangle.cs

#LineLine coverage
 1//=======================================================================
 2// FiniteSlabSectionFrame.Triangle.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/// <content>Closed triangle admission using the shared finite section and one exact plane witness.</content>
 13internal readonly partial struct FiniteSlabSectionFrame
 14{
 15    /// <summary>Tests closed triangle overlap without producing contact depths or rounded anchors.</summary>
 16    internal bool IntersectsTriangle(FixedTriangle triangle, ReadOnlySpan<Vector2d> prismOffsets = default)
 17    {
 932818        for (int edge = 0; edge < 3; edge++)
 375119            if (IntersectsSegment(triangle.GetEdge(edge), prismOffsets)) return true;
 108920        CapsulePlaneRayFrame plane = _radial.ShapeFrame.HasExactScale
 108921            ? new(triangle, SourceFrame, _radial) : new(triangle, _radial);
 109122        if (plane.NormalSquared.IsZero) return false;
 23        // The slab and its plane section are convex and connected. With no
 24        // closed triangle edge crossing, any overlap contains the whole
 25        // section inside the triangle. One admitted section point decides it.
 26        const int words = 22;
 217427        Span<ulong> values = stackalloc ulong[24 * words]; Span<int> signs = stackalloc int[24];
 217428        Span<ulong> root = stackalloc ulong[_radial.ShapeFrame.HasExactScale ? 13 : 9]; root.Clear();
 108729        ContactQuadratic x = ContactQuadratic.At(values, signs, 0, words),
 217430            y = ContactQuadratic.At(values, signs, 1, words), z = ContactQuadratic.At(values, signs, 2, words),
 217431            d = ContactQuadratic.At(values, signs, 3, words), term = ContactQuadratic.At(values, signs, 4, words),
 217432            work = ContactQuadratic.At(values, signs, 5, words), metric = ContactQuadratic.At(values, signs, 6, words),
 217433            radius = ContactQuadratic.At(values, signs, 7, words), gap = ContactQuadratic.At(values, signs, 8, words);
 434834        x.Clear(); y.Clear(); z.Clear(); d.Clear();
 108735        bool admitted = prismOffsets.IsEmpty
 108736            ? TryGetCurvedPlanePoint(plane, x, y, z, d, term, work, metric, radius, gap, root)
 108737            : TryGetPrismPlanePoint(plane, prismOffsets, x, y, z, d, term, work);
 108738        return admitted && plane.ContainsTrianglePoint(triangle, x, y, z, d, root);
 39    }
 40
 41    private bool TryGetCurvedPlanePoint(in CapsulePlaneRayFrame plane, ContactQuadratic x,
 42        ContactQuadratic y, ContactQuadratic z, ContactQuadratic d, ContactQuadratic term,
 43        ContactQuadratic work, ContactQuadratic metric, ContactQuadratic radius, ContactQuadratic gap, Span<ulong> root)
 44    {
 107045        WideDirection3d n = plane.Normal;
 107046        Signed832 radialMetric = WideArithmetic.AddSigned832(Product(n.X, n.X),
 107047            Product(n.Z, n.Z));
 107048        if (radialMetric.IsZero)
 49        {
 30550            Signed832 extent = Product(Absolute(n.Y), _cap);
 60051            if (WideArithmetic.SubtractSigned832(Absolute(plane.PlaneConstant), extent).Sign > 0) return false;
 3052            y.Set(plane.PlaneConstant); y.MultiplySign(n.Y.Sign); d.Set(Signed832.ExtendValue(Absolute(n.Y)));
 1053            return true;
 54        }
 148255        if (_radial.ShapeFrame.HasExactScale) WideArithmetic.GetMagnitude(radialMetric, root);
 56        else
 57        {
 58            // The rigid normal retains the original 576-bit radial metric.
 59            // Its compact root bank intentionally has only nine limbs.
 4860            Signed576 compactMetric = Signed576.NarrowValue(radialMetric);
 4861            WideArithmetic.GetMagnitude(compactMetric, root);
 62        }
 76563        Signed320 r = Signed320.NarrowValue(WideArithmetic.MultiplySigned320(_radial.ShapeFrame.CoordinateDenominator, _
 76564        Signed832 axialSupport = WideArithmetic.AddSigned832(Product(Absolute(n.Y), _cap),
 76565            Product(Absolute(n.Z), _radial.ShapeFrame.Cap));
 66        // For symmetric S, q=(k/support(N))*supportPoint(N) is admitted.
 67        // Clear the common sqrt(radialMetric) denominator before composing
 68        // its coordinates: qD=R*radialMetric+axialSupport*sqrt(radialMetric).
 153069        metric.Set(radialMetric); radius.Set(Signed832.ExtendValue(r));
 76570        ContactQuadratic.Multiply(metric, radius, root, d);
 229571        term.Set(axialSupport); term.Rational.CopyTo(d.Radical); d.Signs[1] = axialSupport.Sign;
 229572        gap.Clear(); term.Set(Absolute(plane.PlaneConstant)); term.Rational.CopyTo(gap.Radical);
 153073        gap.Signs[1] = term.Signs[0]; gap.Add(d, -1);
 126974        if (gap.Sign(root) > 0) return false;
 26175        if (d.Sign(root) == 0)
 76        {
 77            // A zero-width core orthogonal to this plane has only k=0.
 78            // Its origin is a valid section point, including a line family.
 179            d.Set(Signed832.ExtendValue(Signed320.One));
 180            return true;
 81        }
 26082        term.Set(Product(r, n.X));
 26083        ContactQuadratic.Scale(term, plane.PlaneConstant, x);
 26084        term.Set(Product(r, n.Z));
 26085        ContactQuadratic.Scale(term, plane.PlaneConstant, z);
 26086        term.Set(Signed832.ExtendValue(Signed(_cap, n.Y.Sign)));
 78087        ContactQuadratic.Scale(term, plane.PlaneConstant, work); work.Rational.CopyTo(y.Radical); y.Signs[1] = work.Sign
 26088        term.Set(Signed832.ExtendValue(Signed(_radial.ShapeFrame.Cap, n.Z.Sign)));
 78089        ContactQuadratic.Scale(term, plane.PlaneConstant, work); work.Rational.CopyTo(z.Radical); z.Signs[1] = work.Sign
 90        // Coordinate coefficients <930 bits and denominator <730 bits fit
 91        // 22 limbs; ContainsTrianglePoint derives its wider wall-product bank.
 26092        return true;
 93    }
 94
 95    private bool TryGetPrismPlanePoint(in CapsulePlaneRayFrame plane, ReadOnlySpan<Vector2d> offsets,
 96        ContactQuadratic x, ContactQuadratic y, ContactQuadratic z, ContactQuadratic d,
 97        ContactQuadratic term, ContactQuadratic work)
 98    {
 1799        _ = GetPrismWinding(offsets);
 17100        Signed320 scale = WideArithmetic.AddSigned320(_radial.ShapeFrame.CoordinateDenominator, _radial.ShapeFrame.Coord
 34101        WideAxis3 low = default, high = default;
 34102        Signed832 lowValue = default, highValue = default;
 170103        for (int index = 0; index < offsets.Length; index++)
 104        {
 68105            WideAxis3 point = new(Signed320.NarrowValue(WideArithmetic.MultiplySigned320(scale, Signed192.Raw(offsets[in
 68106                Signed320.NarrowValue(WideArithmetic.MultiplySigned320(scale, Signed192.Raw(offsets[index].Y))));
 68107            Signed832 value = WideDirection3d.Dot(plane.Normal, point);
 102108            if (index == 0 || WideArithmetic.SubtractSigned832(value, lowValue).Sign < 0) { low = point; lowValue = valu
 130109            if (index == 0 || WideArithmetic.SubtractSigned832(value, highValue).Sign > 0) { high = point; highValue = v
 110        }
 17111        Signed320 cap = Signed(_cap, plane.Normal.Y.Sign);
 34112        low = new(low.X, WideArithmetic.Negate(cap), low.Z); high = new(high.X, cap, high.Z);
 34113        lowValue = WideDirection3d.Dot(plane.Normal, low); highValue = WideDirection3d.Dot(plane.Normal, high);
 17114        if (WideArithmetic.SubtractSigned832(plane.PlaneConstant, lowValue).Sign < 0
 24115            || WideArithmetic.SubtractSigned832(plane.PlaneConstant, highValue).Sign > 0) return false;
 10116        Signed832 difference = WideArithmetic.SubtractSigned832(highValue, lowValue);
 117        // A valid convex footprint and positive thickness span all three
 118        // dimensions, so a nonzero plane normal has positive support width.
 119        System.Diagnostics.Debug.Assert(difference.Sign > 0);
 10120        Signed832 fraction = WideArithmetic.SubtractSigned832(plane.PlaneConstant, lowValue);
 10121        d.Set(difference);
 80122        for (int axis = 0; axis < 3; axis++)
 123        {
 30124            ContactQuadratic coordinate = axis == 0 ? x : axis == 1 ? y : z;
 60125            Signed320 first = Component(low, axis), last = Component(high, axis);
 60126            term.Set(Signed832.ExtendValue(first)); ContactQuadratic.Scale(term, difference, coordinate);
 30127            term.Set(Signed832.ExtendValue(WideArithmetic.SubtractSigned320(last, first)));
 60128            ContactQuadratic.Scale(term, fraction, work); coordinate.Add(work);
 129        }
 10130        return true;
 131    }
 132
 133    private static Signed832 Product(Signed576 first, Signed576 second) =>
 2140134        WideArithmetic.MultiplySigned576ToSigned832(first, second);
 135    private static Signed832 Product(Signed576 first, Signed320 second) =>
 1835136        WideArithmetic.MultiplySigned576ToSigned832(first, second);
 137    private static Signed832 Product(Signed320 first, Signed576 second) =>
 520138        WideArithmetic.MultiplySigned576ToSigned832(second, first);
 1845139    private static Signed576 Absolute(Signed576 value) => value.Sign < 0 ? WideArithmetic.SubtractSigned576(default, val
 1070140    private static Signed832 Absolute(Signed832 value) => value.Sign < 0 ? WideArithmetic.SubtractSigned832(default, val
 537141    private static Signed320 Signed(Signed320 value, int sign) => sign == 0 ? default : sign < 0 ? WideArithmetic.Negate
 60142    private static Signed320 Component(WideAxis3 value, int axis) => axis == 0 ? value.X : axis == 1 ? value.Y : value.Z
 143}

Methods/Properties

get_SourceFrame()
get_RadialFrame()
get_Cap()
Transform(FixedMathSharp.Vector3d)
get_PointWords()
get_RootWords()
.ctor(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Signed320)
.ctor(FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion,FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,System.Boolean)
.ctor(FixedMathSharp.Geometry.ScaledRigidFrame3d&,FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,System.Boolean)
ContainsPoint(FixedMathSharp.Vector3d)
ContainsPoint(FixedMathSharp.Vector3d,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
IntersectsSegment(FixedMathSharp.Geometry.FixedSegment,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
IntersectsTransformedSegment(FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.RationalSegmentInterval&)
IntersectsSegment(FixedMathSharp.Geometry.FixedSegment,FixedMathSharp.Geometry.RationalSegmentInterval&)
TryGetFirstSegmentParameter(FixedMathSharp.Geometry.FixedSegment,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,System.Span`1<System.UInt64>)
TryGetFirstProjectedSegmentParameter(FixedMathSharp.Geometry.FixedSegment,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,System.Span`1<System.UInt64>)
TryGetPrismSegmentParameter(FixedMathSharp.Geometry.FixedSegment,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,System.Span`1<System.UInt64>,System.Boolean)
PrismWall(FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
GetPrismWinding(System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
IntersectsSegment(FixedMathSharp.Geometry.FixedSegment)
TryGetFirstSegmentParameter(FixedMathSharp.Geometry.FixedSegment,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,System.Span`1<System.UInt64>)
TryGetFirstSegmentParameter(FixedMathSharp.Geometry.FixedSegment,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,System.Span`1<System.UInt64>,System.Boolean)
TryGetPrimitive(FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideAxis3,System.Int32,FixedMathSharp.Signed832&,FixedMathSharp.Signed832&,FixedMathSharp.Signed832&,FixedMathSharp.Signed320&,FixedMathSharp.Signed320&,FixedMathSharp.Signed320&,FixedMathSharp.Signed320&,System.Boolean)
Compare(FixedMathSharp.Signed320,FixedMathSharp.Signed320,FixedMathSharp.Signed320,FixedMathSharp.Signed320)
SetFirstQuadraticParameter(FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed320,FixedMathSharp.Signed320,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,System.Span`1<System.UInt64>)
Radial(FixedMathSharp.Geometry.WideAxis3)
Difference(FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideAxis3)
IntersectsTriangle(FixedMathSharp.Geometry.FixedTriangle,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
TryGetCurvedPlanePoint(FixedMathSharp.Geometry.CapsulePlaneRayFrame&,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,System.Span`1<System.UInt64>)
TryGetPrismPlanePoint(FixedMathSharp.Geometry.CapsulePlaneRayFrame&,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic)
Product(FixedMathSharp.Signed576,FixedMathSharp.Signed576)
Product(FixedMathSharp.Signed576,FixedMathSharp.Signed320)
Product(FixedMathSharp.Signed320,FixedMathSharp.Signed576)
Absolute(FixedMathSharp.Signed576)
Absolute(FixedMathSharp.Signed832)
Signed(FixedMathSharp.Signed320,System.Int32)
Component(FixedMathSharp.Geometry.WideAxis3,System.Int32)