< Summary

Line coverage
100%
Covered lines: 552
Uncovered lines: 0
Coverable lines: 552
Total lines: 1001
Line coverage: 100%
Branch coverage
100%
Covered branches: 492
Total branches: 492
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
File 1: .ctor(...)100%11100%
File 1: .ctor(...)100%11100%
File 1: get_Item(...)100%66100%
File 1: .ctor(...)100%11100%
File 1: get_Shape()100%11100%
File 1: .ctor(...)100%11100%
File 1: WithActive(...)100%11100%
File 1: WithDisk(...)100%11100%
File 1: WithoutSolvedDisks()100%11100%
File 1: IsActive(...)100%44100%
File 1: AccumulateTriangle(...)100%11100%
File 1: AccumulateSegment(...)100%22100%
File 1: AccumulatePhysicalSupportTriangle(...)100%11100%
File 1: AccumulatePlane(...)100%11100%
File 1: AccumulateDomain(...)100%11100%
File 1: AccumulateDomain(...)100%6262100%
File 1: AccumulatePhysicalSupport(...)100%8484100%
File 1: AccumulateSupportLine(...)100%66100%
File 1: FootprintProjection(...)100%11100%
File 1: AccumulateHorizontalPlane(...)100%3030100%
File 1: AddInterval(...)100%11100%
File 1: Accumulate(...)100%1010100%
File 1: AccumulateAxial(...)100%1212100%
File 1: ThreePlanes(...)100%66100%
File 1: Determinant(...)100%3030100%
File 1: Process(...)100%1818100%
File 1: ProcessRational(...)100%66100%
File 1: Admitted(...)100%1818100%
File 1: Coordinate(...)100%11100%
File 1: IsClearanceExit(...)100%5858100%
File 1: TwoPlanesDisk(...)100%2626100%
File 1: PlaneDisk(...)100%1212100%
File 1: PlaneChart(...)100%44100%
File 1: BuildConic(...)100%4242100%
File 1: Cross(...)100%11100%
File 1: ProcessChart(...)100%1010100%
File 1: Transform(...)100%2020100%
File 1: Choose(...)100%22100%
File 1: Degree(...)100%44100%
File 1: P(...)100%11100%
File 1: S(...)100%11100%
File 1: S(...)100%11100%
File 1: S(...)100%11100%
File 1: ScaledOffset(...)100%11100%
File 1: Negate(...)100%11100%
File 1: Signed(...)100%22100%
File 1: Negate(...)100%11100%
File 1: Signed(...)100%22100%
File 1: Signed(...)100%11100%
File 1: Component(...)100%44100%
File 1: Component(...)100%44100%
File 1: Difference(...)100%11100%
File 1: Wall(...)100%11100%
File 1: Wall(...)100%11100%
File 1: DomainEdge(...)100%88100%
File 2: AccumulateNativeLine(...)100%11100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// FiniteSlabRayExtrema.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/// <summary>Finite-domain clearance of one flat-capped planar convex primitive.</summary>
 19/// <content>Solves shared finite-domain linear and radial active sets.</content>
 20internal static partial class FiniteSlabRayExtrema
 21{
 22    // Width ledger: exact rigid points/edges <198 bits; conditioned normal
 23    // components <268; prism linear rows <334; chart radial coordinates <532;
 24    // conic coefficients <1065; PlaneDisk elimination retains quadratic
 25    // coefficients <2133. The single radial constraint produces only
 26    // quadratic roots; reconstructed point coefficients and final depth/sign
 27    // products remain <3400 bits.
 28    // Rigid calls retain the 64-word bank. For exact affine ingress, the
 29    // full clipping rows have <832 bits and coordinates/rays <352. A plane
 30    // chart has <1186-bit coordinates, <2374-bit conics and <4751-bit
 31    // eliminated quadratics. Reconstructed witnesses stay <3563 bits;
 32    // their squared physical metric stays <7834, within 128 words.
 33    private const int Words = FiniteSlabPolynomial.Words;
 34    private readonly struct Linear
 35    {
 36        internal readonly Signed832 A, B, C, D;
 37        internal Linear(Signed832 a, Signed832 b, Signed832 c, Signed832 d)
 3221038        { A = a; B = b; C = c; D = d; }
 39        internal Linear(Signed576 a, Signed576 b, Signed576 c, Signed576 d)
 1267640            : this(Signed832.ExtendValue(a), Signed832.ExtendValue(b), Signed832.ExtendValue(c), Signed832.ExtendValue(d
 76959041        internal Signed832 this[int index] => index == 0 ? A : index == 1 ? B : index == 2 ? C : D;
 42    }
 43    private readonly struct Radial
 44    {
 45        internal readonly WideAxis3 A, E, F;
 46        internal readonly WideDirection3d N;
 47        internal readonly Signed320 Radius;
 48        internal Radial(WideAxis3 a, WideAxis3 e, WideAxis3 f, WideDirection3d n, Signed320 radius)
 580849        { A = a; E = e; F = f; N = n; Radius = radius; }
 50    }
 51    private readonly ref struct Problem
 52    {
 53        internal readonly ReadOnlySpan<Linear> Lines;
 54        internal readonly ReadOnlySpan<Radial> Disks;
 55        internal readonly FixedTriangle Triangle;
 56        internal readonly int Orientation;
 57        internal readonly FiniteSlabRayCandidateVisitor? Visitor;
 58        private readonly ReadOnlySpan<Radial> _shape;
 771459        internal ref readonly Radial Shape => ref _shape[0];
 60        internal readonly Signed320 HalfThickness, CoreCap;
 61        internal readonly bool HasCore, IsPrism;
 62        internal readonly int ExitLinearStart;
 63        internal readonly int DomainEdgeMask;
 64        internal readonly int ActiveFirst, ActiveSecond, ActiveThird, SolvedDisks;
 65        internal readonly int DomainLineCount;
 66        internal readonly int ExitRegion;
 67        internal readonly int FieldWords;
 68        internal readonly Span<ulong> VertexValues;
 69        internal readonly Span<sbyte> VertexSigns;
 70        internal Problem(ReadOnlySpan<Linear> lines, ReadOnlySpan<Radial> disks,
 71            FixedTriangle triangle, int orientation, FiniteSlabRayCandidateVisitor? visitor,
 72            ReadOnlySpan<Radial> shape, Signed320 halfThickness, Signed320 coreCap, bool hasCore, bool isPrism, int exit
 73            Span<ulong> vertexValues, Span<sbyte> vertexSigns,
 74            int domainEdgeMask = 0, int activeFirst = -1, int activeSecond = -1, int activeThird = -1, int solvedDisks =
 75            int domainLineCount = 3, int exitRegion = 0, int fieldWords = Words)
 76        {
 12077077            Lines = lines; Disks = disks; Triangle = triangle; Orientation = orientation; Visitor = visitor;
 9661678            _shape = shape; HalfThickness = halfThickness; CoreCap = coreCap; HasCore = hasCore;
 4830879            IsPrism = isPrism; ExitLinearStart = exitLinearStart;
 2415480            DomainEdgeMask = domainEdgeMask;
 9661681            ActiveFirst = activeFirst; ActiveSecond = activeSecond; ActiveThird = activeThird; SolvedDisks = solvedDisks
 2415482            DomainLineCount = domainLineCount;
 4830883            ExitRegion = exitRegion; FieldWords = fieldWords;
 4830884            VertexValues = vertexValues; VertexSigns = vertexSigns;
 2415485        }
 1999886        internal Problem WithActive(int first, int second = -1, int third = -1) => new(Lines, Disks, Triangle, Orientati
 1999887            _shape, HalfThickness, CoreCap, HasCore, IsPrism, ExitLinearStart, VertexValues, VertexSigns,
 1999888            DomainEdge(first, DomainLineCount) | DomainEdge(second, DomainLineCount) | DomainEdge(third, DomainLineCount
 1999889            first, second, third, SolvedDisks, DomainLineCount, ExitRegion, FieldWords);
 314690        internal Problem WithDisk(int disk) => new(Lines, Disks, Triangle, Orientation, Visitor,
 314691            _shape, HalfThickness, CoreCap, HasCore, IsPrism, ExitLinearStart, VertexValues, VertexSigns, DomainEdgeMask
 314692            ActiveFirst, ActiveSecond, ActiveThird, SolvedDisks | (1 << disk), DomainLineCount, ExitRegion, FieldWords);
 13893        internal Problem WithoutSolvedDisks() => new(Lines, Disks, Triangle, Orientation, Visitor,
 13894            _shape, HalfThickness, CoreCap, HasCore, IsPrism, ExitLinearStart, VertexValues, VertexSigns, DomainEdgeMask
 13895            ActiveFirst, ActiveSecond, ActiveThird, domainLineCount: DomainLineCount,
 13896            exitRegion: ExitRegion, fieldWords: FieldWords);
 4778997        internal bool IsActive(int index) => index == ActiveFirst || index == ActiveSecond || index == ActiveThird;
 98    }
 99
 100    /// <summary>
 101    /// Accumulates the maximum nonnegative intersection parameter q+tN,
 102    /// where q belongs to the finite triangle and q+tN belongs to the slab.
 103    /// The source q need not intersect the slab at parameter zero. Empty offsets
 104    /// select a circle/stadium; nonempty offsets select a convex prism. The
 105    /// plane metric belongs to frame, never to the domain triangle's winding
 106    /// or cross-product magnitude. Candidate callbacks are synchronous.
 107    /// </summary>
 108    internal static void AccumulateTriangle(in FiniteSlabRayFrame frame, FixedTriangle triangle,
 109        ReadOnlySpan<Vector2d> prismOffsets, int orientation, ref FiniteSlabRaySelection maximum,
 110        FiniteSlabRayCandidateVisitor? visitor = null) =>
 130111        AccumulateDomain(frame, triangle, prismOffsets, orientation, true, false, ref maximum, visitor);
 112
 113    /// <summary>Clips the original segment parameter without rounding either rational cut point.</summary>
 114    internal static void AccumulateSegment(in FiniteSlabRayFrame frame, FixedSegment segment, in RationalSegmentInterval
 115        ReadOnlySpan<Vector2d> prismOffsets, int orientation, ref FiniteSlabRaySelection maximum,
 116        FiniteSlabRayCandidateVisitor? visitor = null)
 117    {
 17118        FixedTriangle triangle = new(segment.Start, segment.End, segment.End);
 19119        if (!clip.IsClipped) { AccumulateTriangle(frame, triangle, prismOffsets, orientation, ref maximum, visitor); ret
 16120        Span<RationalSegmentInterval> clips = stackalloc RationalSegmentInterval[1] { clip };
 16121        AccumulateDomain(frame, triangle, prismOffsets, orientation, true, false, ref maximum, visitor, clips);
 16122    }
 123
 124    /// <summary>
 125    /// Clips physical support charts to a nondegenerate coplanar triangle.
 126    /// Nonaxial faces use their point/line charts; free-height supports also
 127    /// clip against original domain edges. Compare with the unbounded plane
 128    /// peak to certify admission; a lower stationary root is not support.
 129    /// </summary>
 130    internal static void AccumulatePhysicalSupportTriangle(in FiniteSlabRayFrame frame, FixedTriangle triangle,
 131        ReadOnlySpan<Vector2d> prismOffsets, int orientation, ref FiniteSlabRaySelection maximum,
 132        FiniteSlabRayCandidateVisitor? visitor = null) =>
 44133        AccumulateDomain(frame, triangle, prismOffsets, orientation, true, true, ref maximum, visitor);
 134
 135    /// <summary>
 136    /// Accumulates the intrinsic slab/plane family without any finite domain
 137    /// inequalities. Hosts must independently certify its retained source
 138    /// projected clearance footprint is covered before using this in a finite
 139    /// mesh domain. Original-section coverage suffices only for axial rays.
 140    /// Axial consumers with representable boundary poles may omit the redundant
 141    /// interior sample; otherwise it remains a potentially sole representable witness.
 142    /// </summary>
 143    internal static void AccumulatePlane(in FiniteSlabRayFrame frame,
 144        ReadOnlySpan<Vector2d> prismOffsets, int orientation, ref FiniteSlabRaySelection maximum,
 145        FiniteSlabRayCandidateVisitor? visitor = null, bool includeInteriorSample = true) =>
 355146        AccumulateDomain(frame, frame.SourcePlane, prismOffsets, orientation, false, false, ref maximum, visitor,
 355147            ReadOnlySpan<RationalSegmentInterval>.Empty, includeInteriorSample);
 148
 149    private static void AccumulateDomain(in FiniteSlabRayFrame frame, FixedTriangle triangle,
 150        ReadOnlySpan<Vector2d> prismOffsets, int orientation, bool finiteDomain, bool physicalSupportOnly,
 151        ref FiniteSlabRaySelection maximum, FiniteSlabRayCandidateVisitor? visitor) =>
 174152        AccumulateDomain(frame, triangle, prismOffsets, orientation, finiteDomain, physicalSupportOnly, ref maximum, vis
 174153            ReadOnlySpan<RationalSegmentInterval>.Empty);
 154
 155    private static void AccumulateDomain(in FiniteSlabRayFrame frame, FixedTriangle triangle,
 156        ReadOnlySpan<Vector2d> prismOffsets, int orientation, bool finiteDomain, bool physicalSupportOnly,
 157        ref FiniteSlabRaySelection maximum, FiniteSlabRayCandidateVisitor? visitor, scoped ReadOnlySpan<RationalSegmentI
 158        bool includeInteriorSample = true, scoped ReadOnlySpan<WideAxis3> nativeSource = default,
 159        scoped ReadOnlySpan<Signed832> nativeRows = default)
 160    {
 565161        if (orientation != -1 && orientation != 1) throw new ArgumentOutOfRangeException(nameof(orientation));
 560162        if (frame.Plane.NormalSquared.IsZero) return;
 558163        WideAxis3 a = nativeSource.IsEmpty ? frame.Section.Transform(triangle.A) : nativeSource[0];
 558164        WideAxis3 e = nativeSource.IsEmpty ? Difference(frame.Section.Transform(triangle.B), a) : nativeSource[1];
 558165        WideAxis3 f = nativeSource.IsEmpty ? Difference(frame.Section.Transform(triangle.C), a) : nativeSource[2];
 558166        WideDirection3d n = Signed(frame.RayNormal, orientation);
 558167        bool axial = n.X.IsZero && n.Z.IsZero;
 558168        if (!finiteDomain && axial)
 169        {
 31170            AccumulateHorizontalPlane(frame, triangle, prismOffsets, orientation, a, e, f, n, ref maximum, visitor, incl
 31171            return;
 172        }
 527173        int pieces = prismOffsets.IsEmpty && frame.HasCore ? 3 : 1;
 527174        int capacity = 10 + prismOffsets.Length + (clips.IsEmpty ? 0 : 2) + nativeRows.Length / 4;
 1054175        Span<Linear> lines = stackalloc Linear[capacity]; Span<Radial> disks = stackalloc Radial[1];
 176        // Active vertices are processed sequentially. Each determinant writes its
 177        // complete bank; retained selections copy their coefficients before reuse.
 178        // Native callers provide a line (dummy mu=0). Its active-set
 179        // coefficients fit the ordinary 4096-bit bank even when the exact
 180        // source denominator requires the section's wider coordinate path.
 527181        int fieldWords = nativeSource.IsEmpty ? frame.FieldWords : FiniteSlabPolynomial.Words;
 527182        Span<ulong> vertexValues = stackalloc ulong[7 * fieldWords];
 527183        Span<sbyte> vertexSigns = stackalloc sbyte[7];
 184        // Every active-set view borrows the same immutable shape for this call.
 527185        Span<Radial> shape = stackalloc Radial[1] { new(a, e, f, n, frame.Radius) };
 2736186        for (int exitPiece = 0; exitPiece < pieces; exitPiece++)
 187        {
 1682188            int count = 0, diskCount = 0;
 841189            if (!nativeRows.IsEmpty)
 190            {
 170191                for (int row = 0; row < nativeRows.Length; row += 4)
 68192                    lines[count++] = new(nativeRows[row], nativeRows[row + 1], nativeRows[row + 2], nativeRows[row + 3])
 193            }
 824194            else if (finiteDomain)
 195            {
 300196                lines[count++] = new(S(1), default, default, default);
 300197                lines[count++] = new(default, S(1), default, default);
 300198                lines[count++] = new(S(-1), S(-1), default, S(1));
 199            }
 841200            if (!clips.IsEmpty)
 201            {
 18202                ref readonly RationalSegmentInterval clip = ref clips[0];
 203                // In the degenerate triangle A,B,B the original parameter is
 204                // lambda+mu. Cut numerators/positive denominators are <319 bits,
 205                // below the existing <334-bit prism rows. Active sets still
 206                // use at most three linear rows: LP determinants <1005 bits,
 207                // radial chart coefficients <1065, eliminated quadratics
 208                // <2133 and final witness/sign products <3400 fit the existing
 209                // 4096-bit retained fields. Constraint count adds no width.
 18210                lines[count++] = new(clip.WideLowerDenominator, clip.WideLowerDenominator, default, Negate(clip.WideLowe
 18211                lines[count++] = new(Negate(clip.WideUpperDenominator), Negate(clip.WideUpperDenominator), default, clip
 212            }
 841213            int domainLineCount = count;
 841214            lines[count++] = new(default, default, S(1), default);
 841215            int exitLinearStart = count;
 216            // Clearance concerns every finite-domain source point that can
 217            // meet the translated slab. Restricting q to the original slab
 218            // misses points entering while it moves, and under-corrects even
 219            // an ordinary tall cylinder against a complete tilted plane.
 841220            AddInterval(lines, ref count, a.Y, e.Y, f.Y, n.Y, frame.Section.Cap);
 841221            if (!prismOffsets.IsEmpty)
 222            {
 192223                int winding = FiniteSlabSectionFrame.GetPrismWinding(prismOffsets);
 192224                Signed320 scale = WideArithmetic.AddSigned320(frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator
 192225                    frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator);
 1824226                for (int edge = 0; edge < prismOffsets.Length; edge++)
 227                {
 1440228                    Vector2d first = prismOffsets[edge], last = prismOffsets[(edge + 1) % prismOffsets.Length];
 720229                    Signed320 dx = Signed320.ExtendValue(WideArithmetic.SubtractSigned192(Signed192.Raw(last.X), Signed1
 720230                    Signed320 dz = Signed320.ExtendValue(WideArithmetic.SubtractSigned192(Signed192.Raw(last.Y), Signed1
 720231                    WideAxis3 offset = new(WideArithmetic.SubtractSigned320(a.X, ScaledOffset(first.X, scale)),
 720232                        a.Y, WideArithmetic.SubtractSigned320(a.Z, ScaledOffset(first.Y, scale)));
 720233                    lines[count++] = new(Signed(Wall(e, dx, dz), winding), Signed(Wall(f, dx, dz), winding),
 720234                        Signed(Wall(n, dx, dz), winding), Signed(Wall(offset, dx, dz), winding));
 235                }
 236            }
 649237            else if (frame.HasCore && exitPiece == 0)
 238            {
 157239                AddInterval(lines, ref count, a.X, e.X, f.X, n.X, frame.Radius);
 157240                AddInterval(lines, ref count, a.Z, e.Z, f.Z, n.Z, frame.CoreCap);
 241            }
 242            else
 243            {
 492244                Signed320 center = frame.HasCore ? Signed(frame.CoreCap, exitPiece == 1 ? -1 : 1) : default;
 492245                WideAxis3 offset = new(a.X, a.Y, WideArithmetic.SubtractSigned320(a.Z, center));
 492246                if (frame.Radius.IsZero)
 247                {
 82248                    AddInterval(lines, ref count, offset.X, e.X, f.X, n.X, default);
 82249                    AddInterval(lines, ref count, offset.Z, e.Z, f.Z, n.Z, default);
 250                }
 410251                else disks[diskCount++] = new(offset, e, f, n, frame.Radius);
 252            }
 841253            Problem problem = new(lines[..count], disks[..diskCount], triangle, orientation, visitor,
 841254                shape, frame.Section.Cap, frame.CoreCap, frame.HasCore,
 841255                !prismOffsets.IsEmpty, exitLinearStart, vertexValues, vertexSigns, domainLineCount: domainLineCount,
 841256                exitRegion: frame.HasCore && exitPiece != 0 ? exitPiece == 1 ? -1 : 1 : 0, fieldWords: fieldWords);
 841257            if (!finiteDomain || physicalSupportOnly && !axial)
 588258                AccumulatePhysicalSupport(problem, frame, prismOffsets, exitPiece, ref maximum);
 301259            else if (axial) AccumulateAxial(problem, n.Y.Sign, ref maximum);
 205260            else Accumulate(problem, ref maximum);
 261        }
 527262    }
 263
 264    private static void AccumulatePhysicalSupport(scoped Problem problem, in FiniteSlabRayFrame frame,
 265        ReadOnlySpan<Vector2d> offsets, int exitPiece, ref FiniteSlabRaySelection maximum)
 266    {
 588267        WideDirection3d n = problem.Shape.N;
 588268        if (offsets.IsEmpty && frame.HasCore)
 269        {
 372270            if (exitPiece == 0 && !n.Z.IsZero) return;
 336271            if (exitPiece != 0 && !n.Z.IsZero && n.Z.Sign != problem.ExitRegion) return;
 284272            if (problem.DomainLineCount != 0 && n.Z.IsZero && exitPiece != 0) return;
 273        }
 274        // Without a finite domain, support of the extrusion is the product
 275        // of an outward Y cap and footprint support; free Y retains both caps.
 496276        int firstCap = problem.ExitLinearStart + (n.Y.Sign > 0 ? 1 : 0);
 496277        int lastCap = n.Y.IsZero ? firstCap + 1 : firstCap;
 496278        Signed576 footprintMaximum = default;
 992279        int firstVertex = 0, lastVertex = 0;
 496280        if (!offsets.IsEmpty)
 1464281            for (int vertex = 0; vertex < offsets.Length; vertex++)
 282            {
 576283                Signed576 projection = FootprintProjection(n, offsets[vertex]);
 576284                int order = WideArithmetic.SubtractSigned576(projection, footprintMaximum).Sign;
 576285                if (vertex == 0 || order > 0)
 524286                { footprintMaximum = projection; firstVertex = lastVertex = vertex; }
 314287                else if (order == 0)
 288                {
 342289                    Vector2d offset = offsets[vertex], first = offsets[firstVertex], last = offsets[lastVertex];
 138290                    if (offset.X < first.X || offset.X == first.X && offset.Y < first.Y) firstVertex = vertex;
 174291                    if (offset.X > last.X || offset.X == last.X && offset.Y > last.Y) lastVertex = vertex;
 292                }
 293            }
 496294        int supportWall = -1;
 295        // A free-height support can end on a triangle edge before either Y cap.
 296        // Keep those original domain constraints as well as the two real caps;
 297        // the same point/line charts then clip the entire physical support face.
 496298        int domainChoices = n.Y.IsZero ? problem.DomainLineCount : 0;
 496299        if (!offsets.IsEmpty && problem.DomainLineCount != 0 && firstVertex != lastVertex)
 120300            for (int edge = 0; edge < offsets.Length; edge++)
 301            {
 120302                Vector2d first = offsets[edge], last = offsets[(edge + 1) % offsets.Length];
 60303                if (first == last) continue;
 60304                if (WideArithmetic.SubtractSigned576(FootprintProjection(n, first), footprintMaximum).Sign != 0
 60305                    || WideArithmetic.SubtractSigned576(FootprintProjection(n, last), footprintMaximum).Sign != 0) conti
 20306                supportWall = problem.ExitLinearStart + 2 + edge;
 20307                break;
 308            }
 2476309        for (int choice = 0; choice < domainChoices + lastCap - firstCap + 1; choice++)
 310        {
 742311            int capIndex = choice < domainChoices ? choice : firstCap + choice - domainChoices;
 742312            ref readonly Linear cap = ref problem.Lines[capIndex];
 742313            if (!offsets.IsEmpty)
 314            {
 228315                if (supportWall >= 0)
 316                {
 20317                    AccumulateSupportLine(problem, capIndex, supportWall, ref maximum);
 20318                    continue;
 319                }
 208320                Signed320 scale = WideArithmetic.AddSigned320(frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator
 208321                    frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator);
 322                // A convex footprint's tied support is one straight face;
 323                // its lexical endpoints omit duplicate/collinear authored samples.
 972324                for (int vertex = 0; vertex < (firstVertex == lastVertex ? 1 : 2); vertex++)
 325                {
 278326                    Vector2d offset = offsets[vertex == 0 ? firstVertex : lastVertex];
 278327                    Linear x = new(S(problem.Shape.E.X), S(problem.Shape.F.X), S(n.X),
 278328                        S(WideArithmetic.SubtractSigned320(problem.Shape.A.X,
 278329                            ScaledOffset(offset.X, scale))));
 278330                    Linear z = new(S(problem.Shape.E.Z), S(problem.Shape.F.Z), S(n.Z),
 278331                        S(WideArithmetic.SubtractSigned320(problem.Shape.A.Z,
 278332                            ScaledOffset(offset.Y, scale))));
 333                    // Direct coordinates retain authored collinear/duplicate
 334                    // corners whose adjacent wall equations are dependent.
 278335                    ThreePlanes(problem.WithActive(capIndex), cap, x, z, ref maximum);
 336                }
 337            }
 514338            else if (frame.HasCore && exitPiece == 0)
 339            {
 108340                int xIndex = problem.ExitLinearStart + 2 + (n.X.Sign > 0 ? 1 : 0);
 108341                if (problem.DomainLineCount != 0)
 342                {
 10343                    AccumulateSupportLine(problem, capIndex, xIndex, ref maximum);
 10344                    continue;
 345                }
 588346                for (int zIndex = problem.ExitLinearStart + 4; zIndex < problem.ExitLinearStart + 6; zIndex++)
 196347                    ThreePlanes(problem.WithActive(capIndex, xIndex, zIndex),
 196348                        cap, problem.Lines[xIndex], problem.Lines[zIndex], ref maximum);
 349            }
 406350            else if (frame.Radius.IsZero)
 351            {
 104352                int xIndex = problem.ExitLinearStart + 2, zIndex = problem.ExitLinearStart + 4;
 52353                ThreePlanes(problem.WithActive(capIndex, xIndex, zIndex),
 52354                    cap, problem.Lines[xIndex], problem.Lines[zIndex], ref maximum);
 355            }
 356            else
 357            {
 354358                Radial disk = problem.Disks[0];
 359                // The existing cap-constrained stationary chart supplies the
 360                // radial support pole without enumerating other active strata.
 354361                PlaneDisk(problem.WithActive(capIndex).WithDisk(0), cap, disk, ref maximum);
 362            }
 363        }
 496364    }
 365
 366    private static void AccumulateSupportLine(scoped Problem problem, int cap, int wall,
 367        ref FiniteSlabRaySelection maximum)
 368    {
 369        // Cap and support wall fix a constant-depth line. Its clipped ends
 370        // occur on an existing footprint/domain constraint, including tangency.
 660371        for (int third = 0; third < problem.Lines.Length; third++)
 372        {
 300373            if (third == cap || third == wall) continue;
 240374            ThreePlanes(problem.WithActive(cap, wall, third), problem.Lines[cap],
 240375                problem.Lines[wall], problem.Lines[third], ref maximum);
 376        }
 30377    }
 378
 666379    private static Signed576 FootprintProjection(WideDirection3d n, Vector2d offset) => WideArithmetic.AddSigned576(
 666380        WideArithmetic.MultiplySigned576(n.X, offset.X.m_rawValue),
 666381        WideArithmetic.MultiplySigned576(n.Z, offset.Y.m_rawValue));
 382
 383    private static void AccumulateHorizontalPlane(in FiniteSlabRayFrame frame, FixedTriangle triangle,
 384        ReadOnlySpan<Vector2d> offsets, int orientation, WideAxis3 a, WideAxis3 e, WideAxis3 f, WideDirection3d n,
 385        ref FiniteSlabRaySelection maximum, FiniteSlabRayCandidateVisitor? visitor, bool includeInteriorSample)
 386    {
 387        // The intrinsic horizontal section is the complete footprint at one
 388        // Y coordinate. Every point has the same rational clearance depth;
 389        // canonical footprint poles/corners cover the constant-depth family
 390        // directly, without solving redundant circle/line quadratics.
 62391        Span<Linear> lines = stackalloc Linear[3]; int count = 0;
 34392        if (!offsets.IsEmpty) _ = FiniteSlabSectionFrame.GetPrismWinding(offsets);
 31393        lines[count++] = new(default, default, S(1), default);
 31394        AddInterval(lines, ref count, a.Y, e.Y, f.Y, n.Y, frame.Section.Cap);
 31395        int capIndex = 1 + (n.Y.Sign > 0 ? 1 : 0);
 31396        Span<Radial> shape = stackalloc Radial[1] { new(a, e, f, n, frame.Radius) };
 31397        Span<ulong> vertexValues = stackalloc ulong[7 * frame.FieldWords];
 31398        Span<sbyte> vertexSigns = stackalloc sbyte[7];
 31399        Problem problem = new(lines, ReadOnlySpan<Radial>.Empty, triangle, orientation, visitor,
 31400            shape, frame.Section.Cap, frame.CoreCap, frame.HasCore,
 31401            !offsets.IsEmpty, 1, vertexValues, vertexSigns, activeFirst: capIndex, domainLineCount: 0, fieldWords: frame
 31402        int samples = !offsets.IsEmpty ? offsets.Length : (frame.HasCore ? 6 : 4) + (includeInteriorSample ? 1 : 0);
 31403        Signed320 scale = WideArithmetic.AddSigned320(frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator,
 31404            frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator);
 376405        for (int index = 0; index < samples; index++)
 406        {
 314407            Signed320 x = default, z = default;
 157408            if (!offsets.IsEmpty)
 409            {
 12410                x = ScaledOffset(offsets[index].X, scale);
 12411                z = ScaledOffset(offsets[index].Y, scale);
 412            }
 145413            else if (frame.HasCore)
 414            {
 33415                if (index < 4)
 40416                { x = Signed(frame.Radius, index % 2 == 0 ? -1 : 1); z = Signed(frame.CoreCap, index < 2 ? -1 : 1); }
 13417                else if (index < 6)
 10418                    z = Signed(WideArithmetic.AddSigned320(frame.CoreCap, frame.Radius), index == 4 ? -1 : 1);
 419            }
 112420            else if (index < 4)
 421            {
 138422                if (index < 2) x = Signed(frame.Radius, index == 0 ? -1 : 1);
 46423                else z = Signed(frame.Radius, index == 2 ? -1 : 1);
 424            }
 157425            Linear qx = new(S(e.X), S(f.X), default, S(WideArithmetic.SubtractSigned320(a.X, x)));
 157426            Linear qz = new(S(e.Z), S(f.Z), default, S(WideArithmetic.SubtractSigned320(a.Z, z)));
 157427            ThreePlanes(problem, lines[capIndex], qx, qz, ref maximum);
 428        }
 31429    }
 430
 431    private static void AddInterval(Span<Linear> lines, ref int count,
 432        Signed320 a, Signed320 e, Signed320 f, Signed576 n, Signed320 cap)
 433    {
 1350434        lines[count++] = new(S(e), S(f), S(n), S(WideArithmetic.AddSigned320(a, cap)));
 1350435        lines[count++] = new(S(Negate(e)), S(Negate(f)), S(Signed(n, -1)), S(WideArithmetic.SubtractSigned320(cap, a)));
 1350436    }
 437
 438    private static void Accumulate(scoped Problem problem, ref FiniteSlabRaySelection maximum)
 439    {
 440        // There is at most one radial quadratic. An isolated maximum has
 441        // three active planes, two planes plus that quadratic, or one plane
 442        // plus its constrained stationary point. A free radial family has a
 443        // null direction preserving depth; the finite Y caps/domain force it
 444        // to one of these real planes, so no separate zero-plane chart is needed.
 3788445        for (int first = 0; first < problem.Lines.Length; first++)
 446        {
 1689447            ref readonly Linear a = ref problem.Lines[first];
 16394448            for (int second = first + 1; second < problem.Lines.Length; second++)
 449            {
 6508450                ref readonly Linear b = ref problem.Lines[second];
 44126451                for (int third = second + 1; third < problem.Lines.Length; third++)
 15555452                    ThreePlanes(problem.WithActive(first, second, third),
 15555453                        a, b, problem.Lines[third], ref maximum);
 16294454                for (int disk = 0; disk < problem.Disks.Length; disk++)
 1639455                    TwoPlanesDisk(problem.WithActive(first, second).WithDisk(disk),
 1639456                        a, b, problem.Disks[disk], ref maximum);
 457            }
 4608458            for (int disk = 0; disk < problem.Disks.Length; disk++)
 615459                PlaneDisk(problem.WithActive(first).WithDisk(disk), a, problem.Disks[disk], ref maximum);
 460        }
 205461    }
 462
 463    private static void AccumulateAxial(scoped Problem problem, int direction,
 464        ref FiniteSlabRaySelection maximum)
 465    {
 466        // Every feasible ray leaves through the outward cap. Enumerating only
 467        // active sets containing it retains all clipped-region extrema and
 468        // cardinal witnesses, without solving irrelevant radial exit charts.
 48469        int capIndex = problem.ExitLinearStart + (direction > 0 ? 1 : 0);
 48470        ref readonly Linear cap = ref problem.Lines[capIndex];
 780471        for (int first = 0; first < problem.Lines.Length; first++)
 472        {
 342473            if (first == capIndex) continue;
 2688474            for (int second = first + 1; second < problem.Lines.Length; second++)
 475            {
 1050476                if (second == capIndex) continue;
 807477                ThreePlanes(problem.WithActive(capIndex, first, second),
 807478                    cap, problem.Lines[first], problem.Lines[second], ref maximum);
 479            }
 1032480            for (int disk = 0; disk < problem.Disks.Length; disk++)
 222481                TwoPlanesDisk(problem.WithActive(capIndex, first).WithDisk(disk), cap, problem.Lines[first], problem.Dis
 482        }
 176483        for (int disk = 0; disk < problem.Disks.Length; disk++)
 40484            PlaneDisk(problem.WithActive(capIndex).WithDisk(disk), cap, problem.Disks[disk], ref maximum);
 48485    }
 486
 487    private static void ThreePlanes(scoped Problem problem, in Linear a, in Linear b, in Linear c,
 488        ref FiniteSlabRaySelection maximum)
 489    {
 17423490        int words = problem.FieldWords;
 17423491        Span<ulong> values = problem.VertexValues;
 17423492        Span<sbyte> signs = problem.VertexSigns;
 34846493        FiniteSlabPolynomial l = P(values, signs, 0), m = P(values, signs, 1),
 69692494            t = P(values, signs, 2), d = P(values, signs, 3), n = P(values, signs, 4), u = P(values, signs, 5, 2);
 17423495        Determinant(d, a, b, c, 0, 1, 2);
 26402496        if (d.IsZero) return;
 16888497        Determinant(l, a, b, c, 3, 1, 2); l.Signs[0] *= -1;
 16888498        Determinant(m, a, b, c, 0, 3, 2); m.Signs[0] *= -1;
 16888499        Determinant(t, a, b, c, 0, 1, 3); t.Signs[0] *= -1;
 25496500        if (d.Signs[0] < 0) { l.Signs[0] *= -1; m.Signs[0] *= -1; t.Signs[0] *= -1; d.Signs[0] = 1; }
 10384501        if (t.Signs[0] < 0) return;
 502        // The LP witness is rational. Its source has no algebraic parameter;
 503        // retain a known half-unit root and the independent rational depth.
 6504504        WideFiniteAxisIntersection.NormalizeFiniteAxisPolynomialPowerOfTwo(values[..(4 * words)], signs[..4]);
 32520505        n.Copy(t); n.Add(d); u.Clear(); u.Add(t); u.Add(d, 2);
 6504506        ProcessRational(problem, l, m, t, d, n, u.Slice(0, 1), ref maximum);
 6504507    }
 508
 509    private static void Determinant(FiniteSlabPolynomial result, in Linear a, in Linear b, in Linear c,
 510        int x, int y, int z)
 511    {
 512        // Rigid rows retain their original 576-bit factors and scratch. Only
 513        // affine coordinates or wide clips require complete 832-bit factors.
 42755514        bool compact = result.FieldWords == Words;
 42755515        int limbs = compact ? 9 : 13;
 42755516        Span<ulong> values = compact ? stackalloc ulong[72] : stackalloc ulong[104];
 128265517        Span<ulong> first = values[..limbs], second = values.Slice(limbs, limbs), third = values.Slice(2 * limbs, limbs)
 85510518            pair = values.Slice(3 * limbs, 2 * limbs), term = values.Slice(5 * limbs, 3 * limbs);
 42755519        result.Clear();
 42755520        int sign = 0;
 598570521        for (int permutation = 0; permutation < 6; permutation++)
 522        {
 256530523            int i = permutation % 3;
 256530524            int j = permutation < 3 ? (i + 1) % 3 : (i + 2) % 3;
 256530525            int k = 3 - i - j;
 513060526            Signed832 av = a[i == 0 ? x : i == 1 ? y : z], bv = b[j == 0 ? x : j == 1 ? y : z],
 256530527                cv = c[k == 0 ? x : k == 1 ? y : z];
 528            // Sparse cap/footprint rows have many exact zero products; they
 529            // need no polynomial scratch initialization or multiplication.
 256530530            if (av.IsZero || bv.IsZero || cv.IsZero) continue;
 47107531            if (compact)
 532            {
 46325533                WideArithmetic.GetMagnitude(Signed576.NarrowValue(av), first);
 46325534                WideArithmetic.GetMagnitude(Signed576.NarrowValue(bv), second);
 46325535                WideArithmetic.GetMagnitude(Signed576.NarrowValue(cv), third);
 536            }
 537            else
 538            {
 2346539                WideArithmetic.GetMagnitude(av, first); WideArithmetic.GetMagnitude(bv, second); WideArithmetic.GetMagni
 540            }
 47107541            WideArithmetic.MultiplyMagnitudes(first, second, pair);
 47107542            WideArithmetic.MultiplyMagnitudes(pair, third, term);
 47107543            WideArithmetic.AddShiftedSignedMagnitude(term, av.Sign * bv.Sign * cv.Sign * (permutation < 3 ? 1 : -1),
 47107544                0, result.Values, ref sign);
 545        }
 42755546        result.Signs[0] = (sbyte)sign;
 42755547    }
 548
 549    private static void Process(scoped Problem problem, scoped FiniteSlabPolynomial equation,
 550        scoped FiniteSlabPolynomial l, scoped FiniteSlabPolynomial m, scoped FiniteSlabPolynomial t,
 551        scoped FiniteSlabPolynomial d, bool parameterIsDepth,
 552        scoped FiniteSlabPolynomial depthN, scoped FiniteSlabPolynomial depthD,
 553        ref FiniteSlabRaySelection maximum)
 554    {
 3154555        int words = problem.FieldWords;
 3237556        if (equation.IsZero) return;
 3071557        WideFiniteAxisIntersection.NormalizeFiniteAxisPolynomialPowerOfTwo(equation.Values, equation.Signs);
 6142558        Span<ulong> cells = stackalloc ulong[64]; Span<int> shifts = stackalloc int[8];
 3071559        FiniteAxisValueRoots roots = WideFiniteAxisIntersection.GetFiniteValueRoots(equation.Values, equation.Signs, cel
 3071560        Span<ulong> cell = stackalloc ulong[WideFiniteAxisIntersection.GetFiniteValueRootCellWords(equation.Values, equa
 3071561        Span<ulong> candidateValues = stackalloc ulong[problem.Visitor is null ? 0 : FiniteSlabRaySelection.GetStorageWo
 3071562        Span<sbyte> candidateSigns = stackalloc sbyte[problem.Visitor is null ? 0 : FiniteSlabRaySelection.SignCount];
 3071563        Span<ulong> half = stackalloc ulong[1] { 1 };
 11096564        for (int ordinal = 0; ordinal < roots.Count; ordinal++)
 565        {
 2477566            FiniteAxisValueRoot root = FiniteAxisValueRoots.GetRoot(roots, ordinal, equation.Values, equation.Signs, cel
 567            // The depth chart maps t>=0 to u>=1/2. Reject its negative
 568            // branch using the already isolated cell before full admission.
 2477569            if (parameterIsDepth && WideFiniteAxisIntersection.CompareFiniteValueRootToDyadic(root, half, 1) < 0) contin
 1752570            if (!Admitted(problem, ref root, l, m, t, d)) continue;
 895571            maximum.Keep(root, roots.Count, l, m, t, d, parameterIsDepth, depthN, depthD,
 895572                problem.Triangle, problem.Orientation, problem.DomainEdgeMask);
 895573            if (problem.Visitor is not null && IsClearanceExit(problem, ref root, l, m, t, d))
 574            {
 187575                FiniteSlabRaySelection candidate = new(candidateValues, candidateSigns, words);
 187576                candidate.Keep(root, roots.Count, l, m, t, d, parameterIsDepth, depthN, depthD,
 187577                    problem.Triangle, problem.Orientation, problem.DomainEdgeMask);
 187578                problem.Visitor(candidate);
 579            }
 580        }
 3071581    }
 582
 583    private static void ProcessRational(scoped Problem problem,
 584        scoped FiniteSlabPolynomial l, scoped FiniteSlabPolynomial m, scoped FiniteSlabPolynomial t,
 585        scoped FiniteSlabPolynomial d, scoped FiniteSlabPolynomial depthN, scoped FiniteSlabPolynomial depthD,
 586        ref FiniteSlabRaySelection maximum)
 587    {
 6504588        int words = problem.FieldWords;
 13008589        Span<ulong> values = stackalloc ulong[2 * words]; Span<sbyte> signs = stackalloc sbyte[2];
 26016590        FiniteSlabPolynomial equation = new(values, signs); equation.Clear(); equation.Set(-1); equation.Set(2, 1);
 13008591        Span<ulong> cell = stackalloc ulong[1]; cell[0] = 1;
 6504592        FiniteAxisValueRoot root = new() { Coefficients = values, Signs = signs,
 6504593            LowerNumerator = cell, DenominatorShift = 1, IsRational = true, Ordinal = 0 };
 11033594        if (!Admitted(problem, ref root, l, m, t, d)) return;
 1975595        maximum.Keep(root, 1, l, m, t, d, false, depthN, depthD,
 1975596            problem.Triangle, problem.Orientation, problem.DomainEdgeMask);
 3440597        if (problem.Visitor is null || !IsClearanceExit(problem, ref root, l, m, t, d)) return;
 510598        Span<ulong> candidateValues = stackalloc ulong[FiniteSlabRaySelection.GetStorageWords(words)];
 510599        Span<sbyte> candidateSigns = stackalloc sbyte[FiniteSlabRaySelection.SignCount];
 510600        FiniteSlabRaySelection candidate = new(candidateValues, candidateSigns, words);
 510601        candidate.Keep(root, 1, l, m, t, d, false, depthN, depthD,
 510602            problem.Triangle, problem.Orientation, problem.DomainEdgeMask);
 510603        problem.Visitor(candidate);
 510604    }
 605
 606    private static bool Admitted(scoped Problem problem, scoped ref FiniteAxisValueRoot root,
 607        scoped FiniteSlabPolynomial l, scoped FiniteSlabPolynomial m,
 608        scoped FiniteSlabPolynomial t, scoped FiniteSlabPolynomial d)
 609    {
 8256610        int words = problem.FieldWords;
 8256611        int denominatorSign = FiniteSlabPolynomial.Sign(ref root, d);
 612        System.Diagnostics.Debug.Assert(denominatorSign != 0);
 16512613        Span<ulong> values = stackalloc ulong[10 * words]; Span<sbyte> signs = stackalloc sbyte[10];
 16512614        FiniteSlabPolynomial q = P(values, signs, 0, 5), term = P(values, signs, 5, 5);
 8256615        if (problem.ExitRegion != 0)
 616        {
 617            // End disks are admitted only on their genuine hemispheres.
 618            // Their cut boundaries z=+/-core already belong to the central
 619            // rectangle's linear strata, so no extra chart is required.
 620            // This exact partition removes covered disk families and their
 621            // duplicate root/depth comparisons without changing the union.
 2775622            Coordinate(problem.Shape, 2, l, m, t, d, q, term);
 5550623            term.Scale(d, Signed(problem.CoreCap, problem.ExitRegion)); q.Add(term, -1);
 3847624            if (FiniteSlabPolynomial.Sign(ref root, q) * denominatorSign * problem.ExitRegion < 0) return false;
 625        }
 97312626        for (int index = 0; index < problem.Lines.Length; index++)
 627        {
 628            // Defining planes are exact algebraic identities of this chart.
 629            // Rechecking them would invoke the full resultant equality bound.
 45471630            if (problem.IsActive(index)) continue;
 31281631            ref readonly Linear line = ref problem.Lines[index];
 156405632            q.Scale(l, line.A); term.Scale(m, line.B); q.Add(term); term.Scale(t, line.C); q.Add(term);
 62562633            term.Scale(d, line.D); q.Add(term);
 35280634            if (FiniteSlabPolynomial.Sign(ref root, q) * denominatorSign < 0) return false;
 635        }
 636        // Prisms and already separated candidates never need radial scratch.
 4958637        if (problem.Disks.IsEmpty) return true;
 2824638        Span<ulong> radialValues = stackalloc ulong[24 * words]; Span<sbyte> radialSigns = stackalloc sbyte[24];
 2824639        FiniteSlabPolynomial x = P(radialValues, radialSigns, 0, 5), z = P(radialValues, radialSigns, 5, 5),
 2824640            square = P(radialValues, radialSigns, 10, 9), second = P(radialValues, radialSigns, 19, 5);
 2824641        Span<ulong> scratchValues = stackalloc ulong[18 * words]; Span<sbyte> scratchSigns = stackalloc sbyte[18];
 1412642        FiniteSlabPolynomial other = new(scratchValues[..(9 * words)], scratchSigns[..9]);
 1412643        FiniteSlabPolynomial radiusSquare = new(scratchValues[(9 * words)..], scratchSigns[9..]);
 5018644        for (int index = 0; index < problem.Disks.Length; index++)
 645        {
 1412646            if ((problem.SolvedDisks & (1 << index)) != 0) continue;
 517647            Radial disk = problem.Disks[index];
 1034648            Coordinate(disk, 0, l, m, t, d, x, term); Coordinate(disk, 2, l, m, t, d, z, term);
 517649            square.Multiply(x, x);
 1034650            other.Multiply(z, z); square.Add(other);
 1551651            second.Scale(d, disk.Radius); radiusSquare.Multiply(second, second); square.Add(radiusSquare, -1);
 832652            if (FiniteSlabPolynomial.Sign(ref root, square) > 0) return false;
 653        }
 1097654        return true;
 655    }
 656
 657    private static void Coordinate(Radial disk, int axis, FiniteSlabPolynomial l, FiniteSlabPolynomial m,
 658        FiniteSlabPolynomial t, FiniteSlabPolynomial d, FiniteSlabPolynomial result, FiniteSlabPolynomial term)
 659    {
 23973660        result.Scale(d, Component(disk.A, axis)); term.Scale(l, Component(disk.E, axis)); result.Add(term);
 31964661        term.Scale(m, Component(disk.F, axis)); result.Add(term); term.Scale(t, Component(disk.N, axis)); result.Add(ter
 7991662    }
 663
 664    private static bool IsClearanceExit(scoped Problem problem, scoped ref FiniteAxisValueRoot root,
 665        scoped FiniteSlabPolynomial l, scoped FiniteSlabPolynomial m,
 666        scoped FiniteSlabPolynomial t, scoped FiniteSlabPolynomial d)
 667    {
 717668        int words = problem.FieldWords;
 5376669        for (int index = problem.ExitLinearStart; index < problem.Lines.Length; index++)
 2318670            if (problem.IsActive(index) && problem.Lines[index].C.Sign < 0
 2665671                && (problem.IsPrism || index < problem.ExitLinearStart + 2)) return true;
 740672        Span<ulong> values = stackalloc ulong[48 * words]; Span<sbyte> signs = stackalloc sbyte[48];
 740673        FiniteSlabPolynomial x = P(values, signs, 0, 5), y = P(values, signs, 5, 5),
 1110674            z = P(values, signs, 10, 5), offset = P(values, signs, 15, 5), term = P(values, signs, 20, 5),
 1110675            square = P(values, signs, 25, 9), other = P(values, signs, 34, 9), dot = P(values, signs, 43, 5);
 370676        int denominatorSign = FiniteSlabPolynomial.Sign(ref root, d);
 370677        Coordinate(problem.Shape, 0, l, m, t, d, x, term);
 370678        Coordinate(problem.Shape, 1, l, m, t, d, y, term);
 370679        Coordinate(problem.Shape, 2, l, m, t, d, z, term);
 2190680        for (int cap = -1; cap <= 1; cap += 2)
 681        {
 735682            if (problem.Shape.N.Y.Sign * cap <= 0) continue;
 30683            offset.Copy(y); term.Scale(d, Signed(problem.HalfThickness, cap)); offset.Add(term, -1);
 20684            if (FiniteSlabPolynomial.Sign(ref root, offset) == 0) return true;
 685        }
 360686        if (problem.IsPrism)
 687        {
 856688            foreach (ref readonly Linear wall in problem.Lines[problem.ExitLinearStart..])
 689            {
 380690                if (wall.C.Sign >= 0) continue;
 264691                offset.Scale(l, wall.A); term.Scale(m, wall.B); offset.Add(term);
 352692                term.Scale(t, wall.C); offset.Add(term); term.Scale(d, wall.D); offset.Add(term);
 168693                if (FiniteSlabPolynomial.Sign(ref root, offset) == 0) return true;
 694            }
 8695            return false;
 696        }
 697        // Axial charts always mark their outward cap active and returned above.
 698        System.Diagnostics.Debug.Assert(!problem.Shape.N.X.IsZero || !problem.Shape.N.Z.IsZero);
 272699        if (problem.HasCore)
 700        {
 701            // A straight side only blocks a strictly outward X ray. Sliding
 702            // along it reaches a farther rim and is not an outward-exit sample.
 346703            if (problem.Shape.Radius.IsZero && !problem.Shape.N.X.IsZero) return true;
 328704            square.Multiply(x, x); term.Scale(d, problem.Shape.Radius); other.Multiply(term, term); square.Add(other, -1
 82705            dot.Scale(x, problem.Shape.N.X);
 82706            if (FiniteSlabPolynomial.Sign(ref root, square) == 0 && FiniteSlabPolynomial.Sign(ref root, dot) * denominat
 707            {
 96708                offset.Copy(z); term.Scale(d, problem.CoreCap); offset.Add(term, -1);
 32709                int upper = FiniteSlabPolynomial.Sign(ref root, offset) * denominatorSign;
 64710                offset.Copy(z); offset.Add(term);
 64711                if (upper <= 0 && FiniteSlabPolynomial.Sign(ref root, offset) * denominatorSign >= 0) return true;
 712            }
 713        }
 324714        for (int side = -1; side <= 1; side += 2)
 715        {
 150716            offset.Copy(z);
 326717            if (problem.HasCore) { term.Scale(d, Signed(problem.CoreCap, side)); offset.Add(term, -1); }
 150718            int hemisphere = FiniteSlabPolynomial.Sign(ref root, offset) * denominatorSign * side;
 150719            if (problem.HasCore && hemisphere < 0) continue;
 336720            square.Multiply(x, x); other.Multiply(offset, offset); square.Add(other);
 336721            term.Scale(d, problem.Shape.Radius); other.Multiply(term, term); square.Add(other, -1);
 112722            if (FiniteSlabPolynomial.Sign(ref root, square) != 0) continue;
 312723            dot.Scale(x, problem.Shape.N.X); term.Scale(offset, problem.Shape.N.Z); dot.Add(term);
 104724            int derivative = FiniteSlabPolynomial.Sign(ref root, dot) * denominatorSign;
 104725            if (derivative > 0 || derivative == 0 && (!problem.HasCore || hemisphere > 0 || problem.Shape.N.Z.Sign * sid
 96726                return true;
 727        }
 12728        return false;
 729    }
 730
 731    private static void TwoPlanesDisk(scoped Problem problem, Linear a, in Linear b, Radial disk,
 732        ref FiniteSlabRaySelection maximum)
 733    {
 2137734        int words = problem.FieldWords;
 4274735        Span<ulong> values = stackalloc ulong[22 * words]; Span<sbyte> signs = stackalloc sbyte[22];
 4274736        FiniteSlabPolynomial l = P(values, signs, 0, 2), m = P(values, signs, 2, 2),
 6411737            t = P(values, signs, 4, 2), d = P(values, signs, 6), n = P(values, signs, 7),
 6411738            equation = P(values, signs, 8, 3), x = P(values, signs, 11, 2), z = P(values, signs, 13, 2),
 8548739            term = P(values, signs, 15, 2), square = P(values, signs, 17, 3), depthD = P(values, signs, 20), depthN = P(
 2137740        Cross(d, a.A, b.B, a.B, b.A);
 2137741        bool depthParameter = !d.IsZero;
 6411742        l.Clear(); m.Clear(); t.Clear();
 2137743        if (depthParameter)
 744        {
 1378745            Cross(l.Slice(0, 1), a.B, b.D, a.D, b.B); Cross(l.Slice(1, 1), a.B, b.C, a.C, b.B);
 1378746            Cross(m.Slice(0, 1), a.D, b.A, a.A, b.D); Cross(m.Slice(1, 1), a.C, b.A, a.A, b.C);
 2067747            t.Add(d, 1, 1); depthN.Clear(); depthD.Clear();
 748        }
 749        else
 750        {
 751            // Dependent lambda/mu rows fix t, leaving a line of source points.
 752            // Its endpoints can be quadratic even though the depth is rational.
 1448753            if (a.A.IsZero && a.B.IsZero)
 754            {
 959755                if (a.C.IsZero || b.A.IsZero && b.B.IsZero) return;
 1425756                n.Set(Negate(a.D)); d.Set(a.C); a = b;
 757            }
 758            else
 759            {
 731760                bool first = !a.A.IsZero;
 731761                Cross(d, first ? a.A : a.B, b.C, first ? b.A : b.B, a.C);
 1035762                if (d.IsZero) return;
 427763                Cross(n, a.D, first ? b.A : b.B, b.D, first ? a.A : a.B);
 764            }
 765            // These active planes already fix t=n/d. A negative value is
 766            // infeasible before any radial polynomial or root is constructed.
 957767            if (n.Signs[0] * d.Signs[0] < 0) return;
 847768            PlaneChart(a, out Signed832 l0, out Signed832 ls, out Signed832 lt,
 847769                out Signed832 m0, out Signed832 ms, out Signed832 mt, out Signed832 denominator);
 4235770            l.Scale(d, l0); term.Scale(n, lt); l.Add(term); term.Scale(d, ls); l.Add(term, 1, 1);
 4235771            m.Scale(d, m0); term.Scale(n, mt); m.Add(term); term.Scale(d, ms); m.Add(term, 1, 1);
 2541772            t.Scale(n, denominator); term.Scale(d, denominator); d.Copy(term.Slice(0, 1));
 3388773            depthN.Copy(t.Slice(0, 1)); depthN.Add(d); depthD.Copy(t.Slice(0, 1)); depthD.Add(d, 2);
 1517774            if (depthD.Signs[0] < 0) { depthN.Signs[0] *= -1; depthD.Signs[0] *= -1; }
 775        }
 3072776        Coordinate(disk, 0, l, m, t, d, x, term); Coordinate(disk, 2, l, m, t, d, z, term);
 4608777        equation.Multiply(x, x); square.Multiply(z, z); equation.Add(square);
 4608778        term.Scale(d, disk.Radius); square.Multiply(term, term); equation.Add(square, -1);
 1536779        ProcessChart(problem, equation, l, m, t, d, depthParameter, depthN, depthD, ref maximum);
 1536780    }
 781
 782    private static void PlaneDisk(scoped Problem problem, in Linear plane, Radial disk,
 783        ref FiniteSlabRaySelection maximum)
 784    {
 1009785        int words = problem.FieldWords;
 1009786        if (plane.A.IsZero && plane.B.IsZero)
 787        {
 226788            if (plane.C.IsZero) return;
 146789            if (-plane.D.Sign * plane.C.Sign < 0) return;
 790            // A constant-depth face is a clipped disk/polygon region. Include
 791            // its intrinsic center/cardinal witnesses, even when the complete
 792            // circle lies inside the triangle and no authored edge meets it.
 138793            Linear x = new(S(disk.E.X), S(disk.F.X), S(disk.N.X), S(disk.A.X));
 138794            Linear z = new(S(disk.E.Z), S(disk.F.Z), S(disk.N.Z), S(disk.A.Z));
 795            // The center is not on the disk that selected this family.
 138796            Problem centerProblem = problem.WithoutSolvedDisks();
 138797            ThreePlanes(centerProblem, plane, x, z, ref maximum);
 552798            for (int index = 0; index < problem.Disks.Length; index++)
 799            {
 138800                TwoPlanesDisk(centerProblem.WithDisk(index), plane, x, problem.Disks[index], ref maximum);
 138801                TwoPlanesDisk(centerProblem.WithDisk(index), plane, z, problem.Disks[index], ref maximum);
 802            }
 138803            return;
 804        }
 1650805        Span<ulong> values = stackalloc ulong[25 * words]; Span<sbyte> signs = stackalloc sbyte[25];
 1650806        FiniteSlabPolynomial conic = P(values, signs, 0, 6), equation = P(values, signs, 6, 3),
 1650807            sn = P(values, signs, 9, 2), sd = P(values, signs, 11),
 1650808            l = P(values, signs, 12, 2), m = P(values, signs, 14, 2),
 1650809            t = P(values, signs, 16, 2), d = P(values, signs, 18),
 2475810            first = P(values, signs, 19), second = P(values, signs, 20), term = P(values, signs, 21, 2),
 1650811            depthN = P(values, signs, 23), depthD = P(values, signs, 24);
 825812        PlaneChart(plane, out Signed832 l0, out Signed832 ls, out Signed832 lt,
 825813            out Signed832 m0, out Signed832 ms, out Signed832 mt, out Signed832 denominator);
 825814        BuildConic(disk, l0, ls, lt, m0, ms, mt, denominator, conic);
 2475815        FiniteSlabPolynomial a = conic.Slice(0, 1), b = conic.Slice(1, 1), c = conic.Slice(2, 1),
 2475816            e = conic.Slice(4, 1), f = conic.Slice(5, 1), h = conic.Slice(3, 1);
 949817        if (a.IsZero) return; // PSD then has no s dependence; a real wall owns the free family.
 3505818        sd.Clear(); sd.Add(a, 2); sn.Clear(); sn.Add(h, -1); sn.Add(b, -1, 1);
 3505819        l.Scale(sd, l0); term.Scale(sn, ls); l.Add(term); term.Scale(sd, lt); l.Add(term, 1, 1);
 3505820        m.Scale(sd, m0); term.Scale(sn, ms); m.Add(term); term.Scale(sd, mt); m.Add(term, 1, 1);
 2103821        d.Scale(sd, denominator); t.Clear(); t.Add(d, 1, 1);
 701822        equation.Clear();
 2804823        first.Multiply(a, f); second.Multiply(h, h); equation.Add(first, 4); equation.Add(second, -1);
 2804824        first.Multiply(a, e); second.Multiply(b, h); equation.Add(first, 4, 1); equation.Add(second, -2, 1);
 2804825        first.Multiply(a, c); second.Multiply(b, b); equation.Add(first, 4, 2); equation.Add(second, -1, 2);
 1402826        depthN.Clear(); depthD.Clear();
 701827        ProcessChart(problem, equation, l, m, t, d, true, depthN, depthD, ref maximum);
 701828    }
 829
 830    private static void PlaneChart(in Linear plane, out Signed832 l0, out Signed832 ls, out Signed832 lt,
 831        out Signed832 m0, out Signed832 ms, out Signed832 mt, out Signed832 denominator)
 832    {
 1672833        if (!plane.B.IsZero)
 834        {
 3393835            denominator = plane.B; l0 = lt = default; ls = denominator;
 3393836            m0 = Negate(plane.D); ms = Negate(plane.A); mt = Negate(plane.C);
 837        }
 838        else
 839        {
 1623840            denominator = plane.A; m0 = mt = default; ms = denominator;
 1623841            l0 = Negate(plane.D); ls = Negate(plane.B); lt = Negate(plane.C);
 842        }
 1672843        if (denominator.Sign < 0)
 844        {
 2732845            denominator = Negate(denominator); l0 = Negate(l0); ls = Negate(ls); lt = Negate(lt);
 2049846            m0 = Negate(m0); ms = Negate(ms); mt = Negate(mt);
 847        }
 1672848    }
 849
 850    private static void BuildConic(Radial disk, Signed832 l0, Signed832 ls, Signed832 lt,
 851        Signed832 m0, Signed832 ms, Signed832 mt, Signed832 denominator, FiniteSlabPolynomial conic)
 852    {
 825853        int words = conic.FieldWords;
 1650854        Span<ulong> values = stackalloc ulong[10 * words]; Span<sbyte> signs = stackalloc sbyte[10];
 1650855        FiniteSlabPolynomial x = P(values, signs, 0, 3), z = P(values, signs, 3, 3),
 3300856            first = P(values, signs, 6), second = P(values, signs, 7), factor = P(values, signs, 8), term = P(values, si
 4950857        for (int axis = 0; axis < 2; axis++)
 858        {
 3300859            FiniteSlabPolynomial coordinate = axis == 0 ? x : z; int component = axis == 0 ? 0 : 2;
 1650860            coordinate.Clear();
 13200861            for (int index = 0; index < 3; index++)
 862            {
 9900863                first.Set(index == 0 ? l0 : index == 1 ? ls : lt); factor.Set(Component(disk.E, component));
 9900864                term.Multiply(first, factor); coordinate.Slice(index, 1).Copy(term);
 9900865                first.Set(index == 0 ? m0 : index == 1 ? ms : mt); factor.Set(Component(disk.F, component));
 9900866                term.Multiply(first, factor); coordinate.Slice(index, 1).Add(term);
 4950867                if (index != 1)
 868                {
 6600869                    first.Set(denominator); factor.Set(index == 0 ? Signed576.ExtendValue(Component(disk.A, component)) 
 6600870                    term.Multiply(first, factor); coordinate.Slice(index, 1).Add(term);
 871                }
 872            }
 873        }
 825874        conic.Clear();
 11550875        for (int index = 0; index < 6; index++)
 876        {
 4950877            int i = index == 0 || index == 1 || index == 3 ? 1 : index == 2 || index == 4 ? 2 : 0;
 4950878            int j = index == 0 ? 1 : index == 1 || index == 2 ? 2 : 0;
 9900879            first.Multiply(x.Slice(i, 1), x.Slice(j, 1)); second.Multiply(z.Slice(i, 1), z.Slice(j, 1));
 9900880            conic.Slice(index, 1).Add(first, i == j ? 1 : 2); conic.Slice(index, 1).Add(second, i == j ? 1 : 2);
 881        }
 3300882        first.Set(denominator); factor.Set(disk.Radius); term.Multiply(first, factor); first.Multiply(term, term);
 825883        conic.Slice(5, 1).Add(first, -1);
 825884    }
 885
 886    private static void Cross(FiniteSlabPolynomial result, Signed832 a, Signed832 b, Signed832 c, Signed832 d)
 887    {
 6051888        int words = result.FieldWords;
 12102889        Span<ulong> values = stackalloc ulong[5 * words]; Span<sbyte> signs = stackalloc sbyte[5];
 12102890        FiniteSlabPolynomial first = P(values, signs, 0), second = P(values, signs, 1),
 18153891            third = P(values, signs, 2), fourth = P(values, signs, 3), term = P(values, signs, 4);
 24204892        first.Set(a); second.Set(b); third.Set(c); fourth.Set(d);
 18153893        result.Multiply(first, second); term.Multiply(third, fourth); result.Add(term, -1);
 6051894    }
 895
 896    private static void ProcessChart(scoped Problem problem, scoped FiniteSlabPolynomial equation,
 897        scoped FiniteSlabPolynomial l, scoped FiniteSlabPolynomial m, scoped FiniteSlabPolynomial t,
 898        scoped FiniteSlabPolynomial d, bool depthParameter,
 899        scoped FiniteSlabPolynomial depthN, scoped FiniteSlabPolynomial depthD,
 900        ref FiniteSlabRaySelection maximum)
 901    {
 2237902        int words = problem.FieldWords;
 4474903        Span<ulong> values = stackalloc ulong[11 * words]; Span<sbyte> signs = stackalloc sbyte[11];
 2237904        FiniteSlabPolynomial transformedEquation = P(values, signs, 0, 3),
 4474905            tl = P(values, signs, 3, 2), tm = P(values, signs, 5, 2),
 4474906            tt = P(values, signs, 7, 2), td = P(values, signs, 9, 2);
 2237907        int degree = Math.Max(Math.Max(Degree(l), Degree(m)), Math.Max(Degree(t), Degree(d)));
 10642908        for (int chart = 0; chart < (depthParameter ? 1 : 2); chart++)
 909        {
 3084910            int sign = chart == 0 ? 1 : -1;
 3084911            Transform(equation, transformedEquation, Degree(equation), depthParameter, sign);
 6168912            Transform(l, tl, degree, depthParameter, sign); Transform(m, tm, degree, depthParameter, sign);
 6168913            Transform(t, tt, degree, depthParameter, sign); Transform(d, td, degree, depthParameter, sign);
 914            // These four homogeneous numerators share one denominator. Strip
 915            // only their common scale, preserving every exact ratio while
 916            // avoiding inherited transform powers in all admission products.
 3084917            WideFiniteAxisIntersection.NormalizeFiniteAxisPolynomialPowerOfTwo(values[(3 * words)..], signs[3..]);
 3084918            Process(problem, transformedEquation, tl, tm, tt, td, depthParameter, depthN, depthD, ref maximum);
 919        }
 2237920        if (!depthParameter && equation.Signs[0] == 0)
 921        {
 210922            transformedEquation.Clear(); transformedEquation.Set(-1); transformedEquation.Set(2, 1);
 70923            Process(problem, transformedEquation, l.Slice(0, 1), m.Slice(0, 1), t.Slice(0, 1), d.Slice(0, 1),
 70924                false, depthN, depthD, ref maximum);
 925        }
 2237926    }
 927
 928    private static void Transform(FiniteSlabPolynomial source, FiniteSlabPolynomial result,
 929        int degree, bool depthParameter, int parameterSign)
 930    {
 931        // t=(2u-1)/(1-u) keeps nonnegative depth in [1/2,1).
 932        // A free line uses s=+/-u/(1-u); its zero endpoint is separate.
 15420933        result.Clear();
 80316934        for (int index = 0; index <= Degree(source); index++)
 111048935            for (int first = 0; first <= (depthParameter ? index : 0); first++)
 164976936                for (int second = 0; second <= degree - index; second++)
 937                {
 51702938                    int exponent = depthParameter ? first + second : index + second;
 51702939                    int factor = Choose(degree - index, second) * (second % 2 == 0 ? 1 : -1);
 80322940                    if (depthParameter) factor *= Choose(index, first) * (1 << first) * ((index - first) % 2 == 0 ? 1 : 
 25386941                    else if (parameterSign < 0 && index % 2 != 0) factor = -factor;
 51702942                    result.Add(source.Slice(index, 1), factor, exponent);
 943                }
 15420944    }
 945    private static int Choose(int n, int k)
 417450946    { int value = 1; for (int i = 1; i <= k; i++) value = value * (n - i + 1) / i; return value; }
 947    private static int Degree(FiniteSlabPolynomial polynomial)
 190556948    { int degree = polynomial.Count - 1; while (degree > 0 && polynomial.Signs[degree] == 0) degree--; return degree; }
 949
 950    private static FiniteSlabPolynomial P(Span<ulong> values, Span<sbyte> signs, int index, int count = 1) =>
 212417951        FiniteSlabPolynomial.At(values, signs, index, count);
 2372952    private static Signed576 S(int value) => S(Signed320.ExtendValue(Signed192.Signed(value)));
 13910953    private static Signed576 S(Signed320 value) => Signed576.ExtendValue(value);
 3532954    private static Signed576 S(Signed576 value) => value;
 955    private static Signed320 ScaledOffset(Fixed64 value, Signed320 scale) =>
 2020956        Signed320.NarrowValue(WideArithmetic.MultiplySigned320(scale, Signed192.Raw(value)));
 4358957    private static Signed320 Negate(Signed320 value) => WideArithmetic.Negate(value);
 3329958    private static Signed320 Signed(Signed320 value, int sign) => sign < 0 ? Negate(value) : value;
 10326959    private static Signed832 Negate(Signed832 value) => WideArithmetic.SubtractSigned832(default, value);
 5904960    private static Signed576 Signed(Signed576 value, int sign) => sign < 0 ? WideArithmetic.SubtractSigned576(default, v
 558961    private static WideDirection3d Signed(WideDirection3d p, int sign) => new(Signed(p.X, sign), Signed(p.Y, sign), Sign
 9641962    private static Signed576 Component(WideDirection3d p, int axis) => axis == 0 ? p.X : axis == 1 ? p.Y : p.Z;
 35523963    private static Signed320 Component(WideAxis3 p, int axis) => axis == 0 ? p.X : axis == 1 ? p.Y : p.Z;
 1082964    private static WideAxis3 Difference(WideAxis3 p, WideAxis3 q) => new(
 1082965        WideArithmetic.SubtractSigned320(p.X, q.X), WideArithmetic.SubtractSigned320(p.Y, q.Y),
 1082966        WideArithmetic.SubtractSigned320(p.Z, q.Z));
 2160967    private static Signed576 Wall(WideAxis3 p, Signed320 x, Signed320 z) => WideArithmetic.SubtractSigned576(
 2160968        WideArithmetic.MultiplySigned320(x, p.Z), WideArithmetic.MultiplySigned320(z, p.X));
 969    private static Signed576 Wall(WideDirection3d p, Signed320 x, Signed320 z) =>
 720970        Signed576.NarrowValue(WideArithmetic.SubtractSigned704(
 720971            WideArithmetic.MultiplySigned576ToSigned704(p.Z, x),
 720972            WideArithmetic.MultiplySigned576ToSigned704(p.X, z)));
 59994973    private static int DomainEdge(int line, int count) => count == 0 ? 0 : line == 0 ? 4 : line == 1 ? 1 : line == 2 ? 2
 974}

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Wide/FiniteAxis/FiniteSlabRayExtrema.NativePrism.cs

#LineLine coverage
 1//=======================================================================
 2// FiniteSlabRayExtrema.NativePrism.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/// <content>Feeds exact native line inequalities into the existing slab active sets.</content>
 15internal static partial class FiniteSlabRayExtrema
 16{
 17    /// <remarks>Source coordinates are A+lambda*E, with the existing solver dummy mu fixed at zero.
 18    /// Selections must be materialized with those same A/E values, not Triangle metadata.</remarks>
 19    internal static void AccumulateNativeLine(in FiniteSlabRayFrame frame, in WideAxis3 a,
 20        in WideAxis3 e, ReadOnlySpan<Signed832> rows,
 21        ref FiniteSlabRaySelection maximum)
 22    {
 1723        ReadOnlySpan<WideAxis3> source = stackalloc WideAxis3[3] { a, e, default };
 1724        AccumulateDomain(frame, default, ReadOnlySpan<Vector2d>.Empty, 1, true, false,
 1725            ref maximum, null, ReadOnlySpan<RationalSegmentInterval>.Empty, nativeSource: source, nativeRows: rows);
 1726    }
 27}

Methods/Properties

.ctor(FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832)
.ctor(FixedMathSharp.Signed576,FixedMathSharp.Signed576,FixedMathSharp.Signed576,FixedMathSharp.Signed576)
get_Item(System.Int32)
.ctor(FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideDirection3d,FixedMathSharp.Signed320)
get_Shape()
.ctor(System.ReadOnlySpan`1<FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear>,System.ReadOnlySpan`1<FixedMathSharp.Geometry.FiniteSlabRayExtrema/Radial>,FixedMathSharp.Geometry.FixedTriangle,System.Int32,FixedMathSharp.Geometry.FiniteSlabRayCandidateVisitor,System.ReadOnlySpan`1<FixedMathSharp.Geometry.FiniteSlabRayExtrema/Radial>,FixedMathSharp.Signed320,FixedMathSharp.Signed320,System.Boolean,System.Boolean,System.Int32,System.Span`1<System.UInt64>,System.Span`1<System.SByte>,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32)
WithActive(System.Int32,System.Int32,System.Int32)
WithDisk(System.Int32)
WithoutSolvedDisks()
IsActive(System.Int32)
AccumulateTriangle(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.FixedTriangle,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,System.Int32,FixedMathSharp.Geometry.FiniteSlabRaySelection&,FixedMathSharp.Geometry.FiniteSlabRayCandidateVisitor)
AccumulateSegment(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.FixedSegment,FixedMathSharp.Geometry.RationalSegmentInterval&,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,System.Int32,FixedMathSharp.Geometry.FiniteSlabRaySelection&,FixedMathSharp.Geometry.FiniteSlabRayCandidateVisitor)
AccumulatePhysicalSupportTriangle(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.FixedTriangle,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,System.Int32,FixedMathSharp.Geometry.FiniteSlabRaySelection&,FixedMathSharp.Geometry.FiniteSlabRayCandidateVisitor)
AccumulatePlane(FixedMathSharp.Geometry.FiniteSlabRayFrame&,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,System.Int32,FixedMathSharp.Geometry.FiniteSlabRaySelection&,FixedMathSharp.Geometry.FiniteSlabRayCandidateVisitor,System.Boolean)
AccumulateDomain(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.FixedTriangle,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,System.Int32,System.Boolean,System.Boolean,FixedMathSharp.Geometry.FiniteSlabRaySelection&,FixedMathSharp.Geometry.FiniteSlabRayCandidateVisitor)
AccumulateDomain(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.FixedTriangle,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,System.Int32,System.Boolean,System.Boolean,FixedMathSharp.Geometry.FiniteSlabRaySelection&,FixedMathSharp.Geometry.FiniteSlabRayCandidateVisitor,System.ReadOnlySpan`1<FixedMathSharp.Geometry.RationalSegmentInterval>,System.Boolean,System.ReadOnlySpan`1<FixedMathSharp.Geometry.WideAxis3>,System.ReadOnlySpan`1<FixedMathSharp.Signed832>)
AccumulatePhysicalSupport(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,FixedMathSharp.Geometry.FiniteSlabRayFrame&,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,System.Int32,FixedMathSharp.Geometry.FiniteSlabRaySelection&)
AccumulateSupportLine(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,System.Int32,System.Int32,FixedMathSharp.Geometry.FiniteSlabRaySelection&)
FootprintProjection(FixedMathSharp.Geometry.WideDirection3d,FixedMathSharp.Vector2d)
AccumulateHorizontalPlane(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.FixedTriangle,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,System.Int32,FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideDirection3d,FixedMathSharp.Geometry.FiniteSlabRaySelection&,FixedMathSharp.Geometry.FiniteSlabRayCandidateVisitor,System.Boolean)
AddInterval(System.Span`1<FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear>,System.Int32&,FixedMathSharp.Signed320,FixedMathSharp.Signed320,FixedMathSharp.Signed320,FixedMathSharp.Signed576,FixedMathSharp.Signed320)
Accumulate(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,FixedMathSharp.Geometry.FiniteSlabRaySelection&)
AccumulateAxial(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,System.Int32,FixedMathSharp.Geometry.FiniteSlabRaySelection&)
ThreePlanes(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear&,FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear&,FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear&,FixedMathSharp.Geometry.FiniteSlabRaySelection&)
Determinant(FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear&,FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear&,FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear&,System.Int32,System.Int32,System.Int32)
Process(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,System.Boolean,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabRaySelection&)
ProcessRational(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabRaySelection&)
Admitted(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,FixedMathSharp.Geometry.FiniteAxisValueRoot&,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial)
Coordinate(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Radial,System.Int32,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial)
IsClearanceExit(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,FixedMathSharp.Geometry.FiniteAxisValueRoot&,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial)
TwoPlanesDisk(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear,FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear&,FixedMathSharp.Geometry.FiniteSlabRayExtrema/Radial,FixedMathSharp.Geometry.FiniteSlabRaySelection&)
PlaneDisk(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear&,FixedMathSharp.Geometry.FiniteSlabRayExtrema/Radial,FixedMathSharp.Geometry.FiniteSlabRaySelection&)
PlaneChart(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Linear&,FixedMathSharp.Signed832&,FixedMathSharp.Signed832&,FixedMathSharp.Signed832&,FixedMathSharp.Signed832&,FixedMathSharp.Signed832&,FixedMathSharp.Signed832&,FixedMathSharp.Signed832&)
BuildConic(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Radial,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Geometry.FiniteSlabPolynomial)
Cross(FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832)
ProcessChart(FixedMathSharp.Geometry.FiniteSlabRayExtrema/Problem,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,System.Boolean,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabRaySelection&)
Transform(FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,System.Int32,System.Boolean,System.Int32)
Choose(System.Int32,System.Int32)
Degree(FixedMathSharp.Geometry.FiniteSlabPolynomial)
P(System.Span`1<System.UInt64>,System.Span`1<System.SByte>,System.Int32,System.Int32)
S(System.Int32)
S(FixedMathSharp.Signed320)
S(FixedMathSharp.Signed576)
ScaledOffset(FixedMathSharp.Fixed64,FixedMathSharp.Signed320)
Negate(FixedMathSharp.Signed320)
Signed(FixedMathSharp.Signed320,System.Int32)
Negate(FixedMathSharp.Signed832)
Signed(FixedMathSharp.Signed576,System.Int32)
Signed(FixedMathSharp.Geometry.WideDirection3d,System.Int32)
Component(FixedMathSharp.Geometry.WideDirection3d,System.Int32)
Component(FixedMathSharp.Geometry.WideAxis3,System.Int32)
Difference(FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideAxis3)
Wall(FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Signed320,FixedMathSharp.Signed320)
Wall(FixedMathSharp.Geometry.WideDirection3d,FixedMathSharp.Signed320,FixedMathSharp.Signed320)
DomainEdge(System.Int32,System.Int32)
AccumulateNativeLine(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.WideAxis3&,FixedMathSharp.Geometry.WideAxis3&,System.ReadOnlySpan`1<FixedMathSharp.Signed832>,FixedMathSharp.Geometry.FiniteSlabRaySelection&)