< Summary

Line coverage
100%
Covered lines: 446
Uncovered lines: 0
Coverable lines: 446
Total lines: 741
Line coverage: 100%
Branch coverage
100%
Covered branches: 236
Total branches: 236
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: get_Words()100%11100%
File 1: GetStorageWords(...)100%11100%
File 1: get_Polynomial()100%11100%
File 1: get_Lambda()100%11100%
File 1: get_Mu()100%11100%
File 1: get_T()100%11100%
File 1: get_D()100%11100%
File 1: get_DepthN()100%11100%
File 1: get_DepthD()100%11100%
File 1: get_RetainedCell()100%11100%
File 1: At(...)100%11100%
File 1: .ctor(...)100%44100%
File 1: Restore(...)100%22100%
File 1: get_CellWords()100%11100%
File 1: get_Metadata()100%11100%
File 1: Restore(...)100%11100%
File 1: CompareDepth(...)100%44100%
File 1: CompareDepthAcrossFrames(...)100%1212100%
File 1: DepthCoefficientWords()100%44100%
File 1: GetPhysicalDepthRatio(...)100%22100%
File 1: CopyDepthCoefficient(...)100%22100%
File 1: Compare(...)100%1010100%
File 1: Keep(...)100%1414100%
File 1: BuildAuthoredCoordinate(...)100%11100%
File 1: ContainsTrianglePoint(...)100%1818100%
File 1: TryGetSourcePointInSamplingFrame(...)100%3030100%
File 1: TryGetContactAnchor(...)100%3030100%
File 1: GetDepth(...)100%11100%
File 1: GetRoundedDepth(...)100%2424100%
File 1: CompareDepth(...)100%11100%
File 1: TryRoundRatio(...)100%2424100%
File 1: TryGetRatioFloorBounds(...)100%2020100%
File 1: IsConstant(...)100%44100%
File 1: Component(...)100%44100%
File 1: Component(...)100%44100%
File 1: Signed(...)100%22100%
File 1: Signed(...)100%22100%
File 1: Difference(...)100%11100%
File 2: CompareNativeDepth(...)100%1010100%
File 2: GetRootParameter(...)100%44100%
File 2: GetNativeLinePointFields(...)100%66100%
File 2: Evaluate(...)100%11100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// FiniteSlabRaySelection.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/// <summary>Independently retained finite-domain ray maximum and exact witness.</summary>
 15/// <content>Retains exact active-set roots and materializes their original source charts.</content>
 16internal ref partial struct FiniteSlabRaySelection
 17{
 18    private const int RetainedCellWords = 8;
 19    internal const int StorageWords = 13 * FiniteSlabPolynomial.Words + RetainedCellWords;
 1007820    private readonly int Words => FieldWords;
 433421    internal static int GetStorageWords(int fieldWords) => 13 * fieldWords + RetainedCellWords;
 22    internal readonly int FieldWords;
 23    internal const int SignCount = 13;
 24    private readonly Span<ulong> _values;
 25    private readonly Span<sbyte> _signs;
 26    private bool _parameterIsDepth;
 27    private int _ordinal, _rootCount, _coefficientCount;
 28    private FixedTriangle _triangle;
 29    private int _orientation;
 30    private int _domainEdgeMask;
 31    private bool _hasCompactCell, _isRational;
 32    private int _denominatorShift;
 33    internal bool HasValue { get; private set; }
 1096534    private readonly FiniteSlabPolynomial Polynomial => At(0, 3);
 587535    private readonly FiniteSlabPolynomial Lambda => At(3, 2);
 585836    private readonly FiniteSlabPolynomial Mu => At(5, 2);
 563837    private readonly FiniteSlabPolynomial T => At(7, 2);
 1098738    private readonly FiniteSlabPolynomial D => At(9, 2);
 477739    private readonly FiniteSlabPolynomial DepthN => At(11, 1);
 477740    private readonly FiniteSlabPolynomial DepthD => At(12, 1);
 446241    private readonly Span<ulong> RetainedCell => _values[(13 * Words)..];
 42    private readonly FiniteSlabPolynomial At(int start, int count) =>
 4887743        FiniteSlabPolynomial.At(_values, _signs, start, count);
 44
 45    internal FiniteSlabRaySelection(Span<ulong> values, Span<sbyte> signs, int fieldWords = FiniteSlabPolynomial.Words)
 46    {
 161047        if (values.Length < GetStorageWords(fieldWords) || signs.Length < SignCount)
 248            throw new ArgumentException("The finite slab ray selection storage is too small.");
 482449        FieldWords = fieldWords; _values = values[..GetStorageWords(fieldWords)]; _signs = signs[..SignCount];
 321650        HasValue = _parameterIsDepth = false; _ordinal = _rootCount = _coefficientCount = _orientation = _domainEdgeMask
 160851        _triangle = default;
 321652        _hasCompactCell = _isRational = false; _denominatorShift = 0;
 160853    }
 54
 55    private readonly FiniteAxisValueRoot Restore(Span<ulong> cell)
 56    {
 162157        if (_hasCompactCell)
 58        {
 323059            RetainedCell.CopyTo(cell); cell[RetainedCellWords..].Clear();
 161560            return new() { Coefficients = Polynomial.Values[..(_coefficientCount * Words)],
 161561                Signs = Polynomial.Signs[.._coefficientCount], LowerNumerator = cell,
 161562                DenominatorShift = _denominatorShift, Ordinal = _ordinal, IsRational = _isRational };
 63        }
 664        return WideFiniteAxisIntersection.GetKnownFiniteValueRoot(
 665            Polynomial.Values[..(_coefficientCount * Words)],
 666            Polynomial.Signs[.._coefficientCount], _ordinal, _rootCount, cell);
 67    }
 162168    private readonly int CellWords => Math.Max(RetainedCellWords,
 162169        WideFiniteAxisIntersection.GetFiniteValueRootCellWords(Polynomial.Values, Polynomial.Signs));
 11570    internal readonly FiniteSlabRaySelectionMetadata Metadata => new(HasValue, _parameterIsDepth,
 11571        _ordinal, _rootCount, _coefficientCount, _orientation, _triangle, _domainEdgeMask,
 11572        _hasCompactCell, _isRational, _denominatorShift);
 73    internal void Restore(FiniteSlabRaySelectionMetadata metadata)
 74    {
 101475        HasValue = metadata.HasValue; _parameterIsDepth = metadata.ParameterIsDepth; _ordinal = metadata.Ordinal;
 67676        _rootCount = metadata.RootCount; _coefficientCount = metadata.CoefficientCount;
 67677        _orientation = metadata.Orientation; _triangle = metadata.Triangle;
 33878        _domainEdgeMask = metadata.DomainEdgeMask;
 67679        _hasCompactCell = metadata.HasCompactCell; _isRational = metadata.IsRational;
 33880        _denominatorShift = metadata.DenominatorShift;
 33881    }
 82
 83    /// <summary>
 84    /// Compares depths sharing the canonical frame. A generic parameter is
 85    /// u=(1+t)/(2+t); constant-depth families retain a separate rational u.
 86    /// </summary>
 87    internal readonly int CompareDepth(scoped in FiniteSlabRaySelection other)
 88    {
 48989        if (!_parameterIsDepth && !other._parameterIsDepth)
 37290            return Compare(false, default, DepthN, DepthD, false, default, other.DepthN, other.DepthD);
 11791        Span<ulong> firstCell = stackalloc ulong[CellWords];
 11792        Span<ulong> secondCell = stackalloc ulong[other.CellWords];
 23493        FiniteAxisValueRoot first = Restore(firstCell), second = other.Restore(secondCell);
 11794        return Compare(_parameterIsDepth, first, DepthN, DepthD,
 11795            other._parameterIsDepth, second, other.DepthN, other.DepthD);
 96    }
 97
 98    /// <summary>Compares physical depths across certified coplanar members in the same slab chart.</summary>
 99    /// <remarks>Positive depths are independent of ray orientation. The caller certifies common physical geometry.</rem
 100    internal readonly int CompareDepthAcrossFrames(scoped in FiniteSlabRaySelection other,
 101        in FiniteSlabRayFrame frame, in FiniteSlabRayFrame otherFrame)
 102    {
 32103        if (!HasValue || !other.HasValue)
 2104            throw new InvalidOperationException("Both slab-ray selections must have an admitted value.");
 30105        if (frame.Plane.NormalSquared.IsZero || !frame.Plane.NormalSquared.Equals(otherFrame.Plane.NormalSquared))
 2106            throw new ArgumentException("The slab-ray frames must share a nonzero reduced normal metric.");
 28107        int axis = !frame.Plane.Normal.X.IsZero ? 0 : !frame.Plane.Normal.Y.IsZero ? 1 : 2;
 108        // The common primitive-normal length cancels. Its selected component
 109        // leaves t*|RayNormal[axis]|/(2D), including each independent conditioning shift.
 110        // LP coefficients <1005 bits; PlaneDisk elimination raises the conic's
 111        // <1065-bit coefficients to <2133-bit retained quadratics. The Mobius
 112        // conversion adds <4 bits, the conditioned component <268 and 2D <132.
 113        // Six extra limbs cover these products; quadratic discriminants and
 114        // the shared ratio owner's later products use complete adaptive widths.
 28115        int words = Math.Max(DepthCoefficientWords(), other.DepthCoefficientWords()) + 6;
 56116        Span<ulong> values = stackalloc ulong[8 * words]; Span<int> signs = stackalloc int[8];
 56117        Span<ulong> firstRoot = stackalloc ulong[2 * words + 1], secondRoot = stackalloc ulong[2 * words + 1];
 56118        ContactQuadratic firstN = ContactQuadratic.At(values, signs, 0, words), firstD = ContactQuadratic.At(values, sig
 56119        ContactQuadratic secondN = ContactQuadratic.At(values, signs, 2, words), secondD = ContactQuadratic.At(values, s
 28120        GetPhysicalDepthRatio(frame, axis, firstRoot, firstN, firstD);
 28121        other.GetPhysicalDepthRatio(otherFrame, axis, secondRoot, secondN, secondD);
 28122        return ContactQuadratic.CompareRatios(firstN, firstD, firstRoot, secondN, secondD, secondRoot);
 123    }
 124
 125    private readonly int DepthCoefficientWords()
 126    {
 64127        ReadOnlySpan<ulong> values = _parameterIsDepth ? Polynomial.Values
 64128            : _values.Slice(11 * Words, 2 * Words);
 64129        int words = 1;
 430130        for (int index = 0; index < values.Length; index += Words)
 151131            words = Math.Max(words, WideArithmetic.GetActiveMagnitudeLength(values.Slice(index, Words)));
 64132        return words;
 133    }
 134
 135    private readonly void GetPhysicalDepthRatio(in FiniteSlabRayFrame frame, int axis,
 136        scoped Span<ulong> radical, scoped ContactQuadratic numerator, scoped ContactQuadratic denominator)
 137    {
 64138        int words = numerator.FieldWords;
 128139        Span<ulong> values = stackalloc ulong[6 * words]; Span<int> signs = stackalloc int[6];
 64140        ContactQuadratic a = ContactQuadratic.At(values, signs, 0, words);
 128141        ContactQuadratic uN = ContactQuadratic.At(values, signs, 1, words), uD = ContactQuadratic.At(values, signs, 2, w
 64142        if (_parameterIsDepth)
 143        {
 23144            GetRootParameter(radical, uN, uD);
 145        }
 146        else
 147        {
 41148            radical.Clear();
 82149            CopyDepthCoefficient(DepthN, 0, uN); CopyDepthCoefficient(DepthD, 0, uD);
 150        }
 192151        uN.CopyTo(numerator); numerator.Add(numerator); numerator.Add(uD, -1);
 128152        uD.CopyTo(denominator); denominator.Add(uN, -1);
 64153        Span<ulong> normal = stackalloc ulong[9];
 64154        WideArithmetic.GetMagnitude(Component(frame.RayNormal, axis), normal);
 128155        ContactQuadratic.Scale(numerator, normal, 1, a); a.CopyTo(numerator);
 64156        Signed320 scale = WideArithmetic.AddSigned320(frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator,
 64157            frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator);
 128158        ContactQuadratic.Scale(denominator, Signed576.ExtendValue(scale), a); a.CopyTo(denominator);
 64159    }
 160
 161    private static void CopyDepthCoefficient(scoped FiniteSlabPolynomial polynomial, int index, scoped ContactQuadratic 
 162    {
 304163        int Words = polynomial.FieldWords;
 304164        value.Clear();
 333165        if (polynomial.Signs[index] == 0) return;
 275166        ReadOnlySpan<ulong> coefficient = polynomial.Values.Slice(index * Words, Words);
 275167        coefficient[..WideArithmetic.GetActiveMagnitudeLength(coefficient)].CopyTo(value.Rational);
 275168        value.Signs[0] = polynomial.Signs[index];
 275169    }
 170
 171    private static int Compare(bool firstIsDepth, scoped FiniteAxisValueRoot first,
 172        scoped FiniteSlabPolynomial firstN, scoped FiniteSlabPolynomial firstD,
 173        bool secondIsDepth, scoped FiniteAxisValueRoot second,
 174        scoped FiniteSlabPolynomial secondN, scoped FiniteSlabPolynomial secondD)
 175    {
 2823176        int Words = Math.Max(firstN.FieldWords, secondN.FieldWords);
 2823177        if (firstIsDepth && secondIsDepth)
 258178            return WideFiniteAxisIntersection.CompareFiniteValueRoots(first, second);
 2565179        Span<ulong> values = stackalloc ulong[3 * Words];
 2565180        Span<sbyte> signs = stackalloc sbyte[3];
 2565181        FiniteSlabPolynomial query = new(values[..(2 * Words)], signs[..2]);
 2565182        if (firstIsDepth || secondIsDepth)
 183        {
 407184            FiniteSlabPolynomial n = firstIsDepth ? secondN : firstN;
 407185            FiniteSlabPolynomial d = firstIsDepth ? secondD : firstD;
 1221186            query.Clear(); query.Add(n, -1); query.Add(d, 1, 1);
 407187            return firstIsDepth ? WideFiniteAxisIntersection.GetSignAtFiniteValueRoot(first, query.Values, query.Signs)
 407188                : -WideFiniteAxisIntersection.GetSignAtFiniteValueRoot(second, query.Values, query.Signs);
 189        }
 4316190        FiniteSlabPolynomial left = query.Slice(0, 1), right = query.Slice(1, 1);
 2158191        FiniteSlabPolynomial difference = new(values[(2 * Words)..], signs[2..]);
 4316192        left.Multiply(firstN, secondD); right.Multiply(secondN, firstD);
 4316193        difference.Copy(left); difference.Add(right, -1);
 2158194        return difference.Signs[0];
 195    }
 196
 197    internal void Keep(scoped FiniteAxisValueRoot root, int rootCount,
 198        scoped FiniteSlabPolynomial lambda, scoped FiniteSlabPolynomial mu,
 199        scoped FiniteSlabPolynomial t, scoped FiniteSlabPolynomial denominator,
 200        bool parameterIsDepth, scoped FiniteSlabPolynomial depthN, scoped FiniteSlabPolynomial depthD,
 201        FixedTriangle triangle, int orientation, int domainEdgeMask)
 202    {
 3586203        if (HasValue)
 204        {
 2334205            Span<ulong> cell = stackalloc ulong[parameterIsDepth || _parameterIsDepth ? CellWords : 0];
 2334206            FiniteAxisValueRoot previous = parameterIsDepth || _parameterIsDepth ? Restore(cell) : default;
 207            // Equal extrema keep the first admitted witness in the explicitly
 208            // ordered active set and authored triangle traversal.
 2334209            if (Compare(parameterIsDepth, root, depthN, depthD,
 4496210                    _parameterIsDepth, previous, DepthN, DepthD) <= 0) return;
 211        }
 4272212        Polynomial.Clear(); root.Coefficients.CopyTo(Polynomial.Values); root.Signs.CopyTo(Polynomial.Signs);
 5696213        Lambda.Copy(lambda); Mu.Copy(mu); T.Copy(t); D.Copy(denominator);
 2848214        DepthN.Copy(depthN); DepthD.Copy(depthD);
 4272215        _parameterIsDepth = parameterIsDepth; _ordinal = root.Ordinal; _rootCount = rootCount;
 5696216        _coefficientCount = root.Signs.Length; _triangle = triangle; _orientation = orientation; HasValue = true;
 1424217        _domainEdgeMask = domainEdgeMask;
 1424218        _hasCompactCell = root.DenominatorShift < RetainedCellWords * 64;
 2848219        _isRational = root.IsRational; _denominatorShift = root.DenominatorShift;
 1424220        RetainedCell.Clear();
 1424221        if (_hasCompactCell)
 1423222            root.LowerNumerator[..WideArithmetic.GetActiveMagnitudeLength(root.LowerNumerator)].CopyTo(RetainedCell);
 1424223    }
 224
 225    private readonly void BuildAuthoredCoordinate(int axis, FiniteSlabPolynomial numerator, FiniteSlabPolynomial term)
 226    {
 2241227        numerator.Scale(D, Signed320.ExtendValue(Signed192.Raw(_triangle.A[axis])));
 2241228        term.Scale(Lambda, Signed320.ExtendValue(WideArithmetic.SubtractSigned192(
 4482229            Signed192.Raw(_triangle.B[axis]), Signed192.Raw(_triangle.A[axis])))); numerator.Add(term);
 2241230        term.Scale(Mu, Signed320.ExtendValue(WideArithmetic.SubtractSigned192(
 4482231            Signed192.Raw(_triangle.C[axis]), Signed192.Raw(_triangle.A[axis])))); numerator.Add(term);
 2241232    }
 233
 234    /// <summary>Admits this exact source point against another member of the same physical slab chart.</summary>
 235    internal readonly bool ContainsTrianglePoint(in FiniteSlabRayFrame target, FixedTriangle triangle,
 236        in FiniteSlabRayFrame source)
 237    {
 63238        if (!HasValue || target.Plane.NormalSquared.IsZero) return false;
 78239        Span<ulong> cell = stackalloc ulong[CellWords]; FiniteAxisValueRoot root = Restore(cell);
 39240        Span<ulong> values = stackalloc ulong[12 * Words];
 39241        Span<sbyte> signs = stackalloc sbyte[12];
 39242        FiniteSlabPolynomial x = FiniteSlabPolynomial.At(values, signs, 0, 2),
 78243            y = FiniteSlabPolynomial.At(values, signs, 2, 2), z = FiniteSlabPolynomial.At(values, signs, 4, 2),
 39244            denominator = FiniteSlabPolynomial.At(values, signs, 6, 2),
 78245            query = FiniteSlabPolynomial.At(values, signs, 8, 2), term = FiniteSlabPolynomial.At(values, signs, 10, 2);
 78246        WideAxis3 a = source.Section.Transform(_triangle.A), e = Difference(source.Section.Transform(_triangle.B), a),
 39247            f = Difference(source.Section.Transform(_triangle.C), a);
 39248        Signed320 targetScale = target.Section.RadialFrame.ShapeFrame.CoordinateDenominator;
 312249        for (int axis = 0; axis < 3; axis++)
 250        {
 117251            FiniteSlabPolynomial coordinate = axis == 0 ? x : axis == 1 ? y : z;
 351252            query.Scale(D, Component(a, axis)); term.Scale(Lambda, Component(e, axis)); query.Add(term);
 234253            term.Scale(Mu, Component(f, axis)); query.Add(term);
 117254            coordinate.Scale(query, targetScale);
 255        }
 39256        denominator.Scale(D, source.Section.RadialFrame.ShapeFrame.CoordinateDenominator);
 39257        int denominatorSign = FiniteSlabPolynomial.Sign(ref root, denominator);
 258        // Source coordinates carry 2Ds and target walls expect 2Dt. Cross
 259        // scaling preserves the exact point; <3400-bit source products plus
 260        // <132-bit scale and <526-bit walls still fit the 4096-bit bank.
 246261        for (int edge = -1; edge < 3; edge++)
 262        {
 263            Signed832 wx, wy, wz, offset;
 108264            if (edge < 0)
 265            {
 78266                wx = Signed832.ExtendValue(target.Plane.Normal.X); wy = Signed832.ExtendValue(target.Plane.Normal.Y);
 78267                wz = Signed832.ExtendValue(target.Plane.Normal.Z); offset = target.Plane.PlaneConstant;
 268            }
 69269            else target.Plane.GetTriangleEdgeWall(triangle, edge, out wx, out wy, out wz, out offset);
 540270            query.Scale(x, wx); term.Scale(y, wy); query.Add(term); term.Scale(z, wz); query.Add(term);
 216271            term.Scale(denominator, offset); query.Add(term, -1);
 108272            int sign = FiniteSlabPolynomial.Sign(ref root, query) * denominatorSign;
 132273            if (edge < 0 ? sign != 0 : sign < 0) return false;
 274        }
 15275        return true;
 276    }
 277
 278    /// <summary>Rounds the source once on the world lattice, returning its offset from the slab center.</summary>
 279    internal readonly bool TryGetSourcePointInSamplingFrame(in FiniteSlabRayFrame frame, out Vector3d point)
 280    {
 58281        point = default;
 60282        if (!HasValue) return false;
 112283        Span<ulong> cell = stackalloc ulong[CellWords]; FiniteAxisValueRoot root = Restore(cell);
 56284        Span<ulong> values = stackalloc ulong[12 * Words];
 56285        Span<sbyte> signs = stackalloc sbyte[12];
 56286        FiniteSlabPolynomial x = FiniteSlabPolynomial.At(values, signs, 0, 2),
 112287            y = FiniteSlabPolynomial.At(values, signs, 2, 2), z = FiniteSlabPolynomial.At(values, signs, 4, 2),
 56288            denominator = FiniteSlabPolynomial.At(values, signs, 6, 2),
 112289            numerator = FiniteSlabPolynomial.At(values, signs, 8, 2), term = FiniteSlabPolynomial.At(values, signs, 10, 
 56290        bool exact = frame.Section.RadialFrame.ShapeFrame.HasExactScale;
 56291        WideRationalBasis3d basis = new(exact ? frame.SlabRotation : frame.Rotation);
 56292        if (exact)
 293        {
 2294            WideAxis3 a = frame.Section.Transform(_triangle.A), e = Difference(frame.Section.Transform(_triangle.B), a),
 1295                f = Difference(frame.Section.Transform(_triangle.C), a);
 8296            for (int axis = 0; axis < 3; axis++)
 297            {
 3298                FiniteSlabPolynomial coordinate = axis == 0 ? x : axis == 1 ? y : z;
 9299                coordinate.Scale(D, Component(a, axis)); term.Scale(Lambda, Component(e, axis)); coordinate.Add(term);
 6300                term.Scale(Mu, Component(f, axis)); coordinate.Add(term);
 301            }
 1302            Signed320 scale = frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator;
 1303            Signed576 divisor = WideArithmetic.MultiplySigned320(WideArithmetic.AddSigned320(scale, scale), basis.Denomi
 1304            denominator.Scale(D, divisor);
 305        }
 306        else
 307        {
 165308            BuildAuthoredCoordinate(0, x, term); BuildAuthoredCoordinate(1, y, term); BuildAuthoredCoordinate(2, z, term
 55309            denominator.Scale(D, Signed320.ExtendValue(basis.Denominator));
 310        }
 311        // Basis coefficients add <130 bits and the origin difference <65;
 312        // subtraction precedes narrowing, including near scalar-range limits.
 444313        for (int axis = 0; axis < 3; axis++)
 314        {
 168315            numerator.Scale(x, Signed320.ExtendValue(axis == 0 ? basis.Xx : axis == 1 ? basis.Xy : basis.Xz));
 336316            term.Scale(y, Signed320.ExtendValue(axis == 0 ? basis.Yx : axis == 1 ? basis.Yy : basis.Yz)); numerator.Add(
 336317            term.Scale(z, Signed320.ExtendValue(axis == 0 ? basis.Zx : axis == 1 ? basis.Zy : basis.Zz)); numerator.Add(
 168318            if (!exact)
 319            {
 165320                term.Scale(denominator, Signed320.ExtendValue(WideArithmetic.SubtractSigned192(
 330321                    Signed192.Raw(frame.Origin[axis]), Signed192.Raw(frame.Center[axis])))); numerator.Add(term);
 322            }
 170323            if (!TryRoundRatio(ref root, numerator, denominator, out Fixed64 component, frame.Center[axis].m_rawValue)) 
 166324            point[axis] = component;
 325        }
 54326        return true;
 327    }
 328
 329    /// <summary>
 330    /// Retains the exit in bounded axial/radial components. A stadium endpoint
 331    /// can exceed the local scalar range even when its translated world anchor
 332    /// is representable; its exact half-core remainder stays in the anchor.
 333    /// </summary>
 334    internal readonly bool TryGetContactAnchor(in FiniteSlabRayFrame frame, out Fixed64 depth, out bool clamped,
 335        out Vector3d source, out FixedPointAnchor anchor)
 336    {
 2780337        depth = default; source = default; clamped = false; anchor = default;
 696338        if (!HasValue) return false;
 1388339        Span<ulong> cell = stackalloc ulong[CellWords]; FiniteAxisValueRoot root = Restore(cell);
 694340        Span<ulong> values = stackalloc ulong[25 * Words];
 694341        Span<sbyte> signs = stackalloc sbyte[25];
 694342        FiniteSlabPolynomial numerator = FiniteSlabPolynomial.At(values, signs, 0, 5);
 694343        FiniteSlabPolynomial term = FiniteSlabPolynomial.At(values, signs, 5, 5);
 694344        FiniteSlabPolynomial divisor = FiniteSlabPolynomial.At(values, signs, 10, 5);
 694345        FiniteSlabPolynomial square = FiniteSlabPolynomial.At(values, signs, 15, 9);
 694346        FiniteSlabPolynomial scalar = FiniteSlabPolynomial.At(values, signs, 24, 1);
 694347        Signed320 scale = WideArithmetic.AddSigned320(frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator,
 694348            frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator);
 694349        divisor.Scale(D, scale);
 694350        WideAxis3 a = frame.Section.Transform(_triangle.A);
 694351        WideAxis3 e = Difference(frame.Section.Transform(_triangle.B), a);
 694352        WideAxis3 f = Difference(frame.Section.Transform(_triangle.C), a);
 1388353        Vector3d axial = default, exit = default;
 694354        FixedPointAnchorTerm3d exactTerm = default;
 694355        int fullHeightCap = 0;
 5534356        for (int axis = 0; axis < 3; axis++)
 357        {
 2076358            BuildAuthoredCoordinate(axis, numerator, term);
 2079359            if (!TryRoundRatio(ref root, numerator, D, out Fixed64 component)) return false;
 2073360            source[axis] = component;
 6219361            numerator.Scale(D, Component(a, axis)); term.Scale(Lambda, Component(e, axis)); numerator.Add(term);
 4146362            term.Scale(Mu, Component(f, axis)); numerator.Add(term);
 4146363            term.Scale(T, Signed(Component(frame.RayNormal, axis), _orientation)); numerator.Add(term);
 2073364            if (axis == 1 && (frame.FullHeight.m_rawValue & 1L) != 0)
 365            {
 5366                term.Scale(D, frame.Section.Cap);
 5367                FiniteSlabPolynomial capQuery = square.Slice(0, 5);
 10368                capQuery.Copy(numerator); capQuery.Add(term, -1);
 7369                if (FiniteSlabPolynomial.Sign(ref root, capQuery) == 0) fullHeightCap = 1;
 370                else
 371                {
 6372                    capQuery.Copy(numerator); capQuery.Add(term);
 5373                    if (FiniteSlabPolynomial.Sign(ref root, capQuery) == 0) fullHeightCap = -1;
 374                }
 375            }
 376            bool bounded;
 2073377            if (frame.HasCore && axis == 2)
 378            {
 320379                FiniteSlabPolynomial endpointQuery = square.Slice(0, 5);
 960380                term.Scale(D, frame.CoreCap); endpointQuery.Copy(numerator); endpointQuery.Add(term, -1);
 320381                int denominatorSign = FiniteSlabPolynomial.Sign(ref root, D);
 320382                int endpoint = FiniteSlabPolynomial.Sign(ref root, endpointQuery) * denominatorSign >= 0 ? 1 : 0;
 320383                if (endpoint == 0)
 384                {
 276385                    endpointQuery.Copy(numerator); endpointQuery.Add(term);
 256386                    if (FiniteSlabPolynomial.Sign(ref root, endpointQuery) * denominatorSign <= 0) endpoint = -1;
 387                }
 320388                if (endpoint == 0)
 389                {
 20390                    bounded = TryRoundRatio(ref root, numerator, divisor, out component);
 391                    System.Diagnostics.Debug.Assert(bounded);
 20392                    axial.Z = component;
 20393                    continue;
 394                }
 300395                numerator.Add(term, -endpoint);
 300396                axial = TriangleCapsuleSlabEndpointWitnesses.GetCore(Vector2d.Forward,
 300397                    frame.Section.RadialFrame.Length, -endpoint, out exactTerm);
 300398                bounded = TryRoundRatio(ref root, numerator, divisor, out component);
 399                System.Diagnostics.Debug.Assert(bounded);
 300400                term.Scale(divisor, Signed320.ExtendValue(Signed192.Raw(component)));
 600401                endpointQuery.Copy(numerator); endpointQuery.Add(term, -1);
 300402                if (FiniteSlabPolynomial.Sign(ref root, endpointQuery) == 0)
 403                {
 404                    // An integral radial term composes exactly with the odd
 405                    // half-core remainder retained by the existing anchor.
 279406                    exit.Z = component;
 279407                    continue;
 408                }
 409                // Otherwise round the endpoint sum once. Retaining an odd
 410                // half-core after rounding its radial fraction would round a
 411                // second time; parity belongs to the complete integer sum.
 21412                exactTerm = default;
 42413                term.Scale(D, Signed(frame.CoreCap, endpoint)); numerator.Add(term);
 42414                term.Scale(divisor, Signed320.ExtendValue(Signed192.Raw(axial.Z))); numerator.Add(term, -1);
 21415                bounded = TryRoundRatio(ref root, numerator, divisor, out component, axial.Z.m_rawValue);
 416                System.Diagnostics.Debug.Assert(bounded);
 21417                exit.Z = component;
 21418                continue;
 419            }
 420            // Exact shape admission bounds local cap/radial/prism components;
 421            // the authored source above can still exceed its scalar range.
 1753422            bounded = TryRoundRatio(ref root, numerator, divisor, out component);
 423            System.Diagnostics.Debug.Assert(bounded);
 1753424            exit[axis] = component;
 425        }
 691426        if (fullHeightCap != 0)
 427            // The cap's half-raw residual composes with any retained odd core;
 428            // applying it after the Z loop prevents a radial rounding reset.
 4429            exactTerm = new(exactTerm.X, FixedPointAnchorTerm3d.GetResidual(Fixed64.One,
 4430                fullHeightCap < 0 ? -frame.FullHeight : frame.FullHeight, Fixed64.Zero, Fixed64.Zero,
 4431                axial.Y, exit.Y), exactTerm.Z);
 691432        anchor = new FixedPointAnchor(frame.Center, frame.SlabRotation, axial, exit, exactTerm);
 691433        GetRoundedDepth(frame, ref root, divisor, square, scalar, out depth, out clamped);
 691434        return true;
 435    }
 436
 437    internal readonly void GetDepth(in FiniteSlabRayFrame frame, out Fixed64 depth, out bool clamped)
 438    {
 439        System.Diagnostics.Debug.Assert(HasValue);
 34440        Span<ulong> cell = stackalloc ulong[CellWords]; FiniteAxisValueRoot root = Restore(cell);
 34441        Span<ulong> values = stackalloc ulong[15 * Words]; Span<sbyte> signs = stackalloc sbyte[15];
 17442        var divisor = FiniteSlabPolynomial.At(values, signs, 0, 5);
 17443        var square = FiniteSlabPolynomial.At(values, signs, 5, 9);
 17444        var scalar = FiniteSlabPolynomial.At(values, signs, 14, 1);
 17445        Signed320 coordinateD = frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator;
 17446        divisor.Scale(D, WideArithmetic.AddSigned320(coordinateD, coordinateD));
 17447        GetRoundedDepth(frame, ref root, divisor, square, scalar, out depth, out clamped);
 17448    }
 449
 450    private readonly void GetRoundedDepth(in FiniteSlabRayFrame frame, scoped ref FiniteAxisValueRoot root,
 451        scoped FiniteSlabPolynomial divisor, scoped FiniteSlabPolynomial square, scoped FiniteSlabPolynomial scalar,
 452        out Fixed64 depth, out bool clamped)
 453    {
 708454        Signed320 coordinateD = frame.Section.RadialFrame.ShapeFrame.CoordinateDenominator;
 708455        Signed320 scale = WideArithmetic.AddSigned320(coordinateD, coordinateD);
 708456        if (IsConstant(T) && IsConstant(D))
 457        {
 516458            Span<ulong> rationalValues = stackalloc ulong[4 * Words];
 516459            Span<int> rationalSigns = stackalloc int[4];
 516460            ContactQuadratic numeratorValue = ContactQuadratic.At(rationalValues, rationalSigns, 0, Words);
 516461            ContactQuadratic denominatorValue = ContactQuadratic.At(rationalValues, rationalSigns, 1, Words);
 1032462            numeratorValue.Clear(); denominatorValue.Clear();
 516463            T.Values[..Words].CopyTo(numeratorValue.Rational);
 516464            D.Values[..Words].CopyTo(denominatorValue.Rational);
 1032465            numeratorValue.Signs[0] = T.Signs[0] * D.Signs[0]; denominatorValue.Signs[0] = 1;
 1032466            Span<ulong> metricValue = stackalloc ulong[13]; WideArithmetic.GetMagnitude(frame.RayNormalSquared, metricVa
 516467            Span<ulong> scaleValue = stackalloc ulong[5];
 516468            WideArithmetic.GetMagnitude(scale, out scaleValue[4], out scaleValue[3], out scaleValue[2], out scaleValue[1
 516469            clamped = !ContactQuadratic.TryRoundRootRatio(numeratorValue, denominatorValue, ReadOnlySpan<ulong>.Empty,
 516470                metricValue, scaleValue, out depth);
 518471            if (clamped) depth = Fixed64.MaxValue;
 516472            return;
 473        }
 474        // Depth uses the same conditioned canonical normal as candidate t;
 475        // numerator²*|N|² / ((2D)²*denominator²) stays exact until this point.
 192476        square.Multiply(T, T);
 192477        Span<ulong> depthValues = stackalloc ulong[27 * Words];
 192478        Span<sbyte> depthSigns = stackalloc sbyte[27];
 192479        FiniteSlabPolynomial metric = FiniteSlabPolynomial.At(depthValues, depthSigns, 0, 9);
 192480        FiniteSlabPolynomial squaredDivisor = FiniteSlabPolynomial.At(depthValues, depthSigns, 9, 9);
 192481        FiniteSlabPolynomial query = FiniteSlabPolynomial.At(depthValues, depthSigns, 18, 9);
 384482        metric.Scale(square, frame.RayNormalSquared); squaredDivisor.Multiply(divisor, divisor);
 384483        ulong lower = 0, upper = 1UL << 63;
 192484        if (TryGetRatioFloorBounds(ref root, metric, squaredDivisor, 1, 1,
 192485                1UL << 63, true, out ulong minimumDepth, out ulong maximumDepth))
 486        {
 487            // This search finds the first integer strictly greater than the
 488            // exact depth, rather than the floor used by coordinate rounding.
 190489            lower = minimumDepth == 1UL << 63 ? minimumDepth : minimumDepth + 1;
 190490            upper = maximumDepth == 1UL << 63 ? maximumDepth : maximumDepth + 1;
 491        }
 711492        while (lower < upper)
 493        {
 519494            ulong mid = lower + ((upper - lower) >> 1);
 772495            if (CompareDepth(ref root, metric, squaredDivisor, query, scalar, mid << 1) >= 0) lower = mid + 1;
 266496            else upper = mid;
 497        }
 498        System.Diagnostics.Debug.Assert(lower > 0);
 192499        ulong floor = lower - 1;
 192500        int comparison = CompareDepth(ref root, metric, squaredDivisor, query, scalar, (floor << 1) | 1);
 192501        ulong rounded = floor + (comparison > 0 || comparison == 0 && (floor & 1) != 0 ? 1UL : 0);
 192502        clamped = rounded > long.MaxValue;
 192503        depth = clamped ? Fixed64.MaxValue : Fixed64.FromRaw((long)rounded);
 192504    }
 505
 506    private static int CompareDepth(scoped ref FiniteAxisValueRoot root,
 507        scoped FiniteSlabPolynomial metric, scoped FiniteSlabPolynomial divisor, scoped FiniteSlabPolynomial query,
 508        scoped FiniteSlabPolynomial scalar, ulong twiceRaw)
 509    {
 711510        int Words = metric.FieldWords;
 1422511        Span<ulong> factor = stackalloc ulong[Words]; factor.Clear();
 711512        Fixed64.Multiply64To128(twiceRaw, twiceRaw, out factor[1], out factor[0]);
 2133513        scalar.Clear(); factor.CopyTo(scalar.Values); scalar.Signs[0] = twiceRaw == 0 ? (sbyte)0 : (sbyte)1;
 711514        query.Multiply(divisor, scalar);
 711515        query.Add(metric, -4);
 711516        return -FiniteSlabPolynomial.Sign(ref root, query);
 517    }
 518
 519    private static bool TryRoundRatio(scoped ref FiniteAxisValueRoot root,
 520        scoped FiniteSlabPolynomial numerator, scoped FiniteSlabPolynomial denominator, out Fixed64 value,
 521        long parityOffset = 0)
 522    {
 4338523        int Words = numerator.FieldWords;
 4338524        value = default;
 4338525        if (IsConstant(numerator) && IsConstant(denominator))
 526        {
 527            System.Diagnostics.Debug.Assert(denominator.Signs[0] != 0);
 3235528            return Fixed64.TryGetSignedRawRatio(numerator.Values[..Words],
 3235529                denominator.Values[..Words],
 3235530                numerator.Signs[0] * denominator.Signs[0] < 0, out value, parityOffset);
 531        }
 1103532        Span<ulong> values = stackalloc ulong[11 * Words];
 1103533        Span<sbyte> signs = stackalloc sbyte[11];
 1103534        FiniteSlabPolynomial query = FiniteSlabPolynomial.At(values, signs, 0, 5);
 1103535        FiniteSlabPolynomial term = FiniteSlabPolynomial.At(values, signs, 5, 5);
 1103536        FiniteSlabPolynomial scalar = FiniteSlabPolynomial.At(values, signs, 10, 1);
 2206537        int sign = FiniteSlabPolynomial.Sign(ref root, numerator), denominatorSign = FiniteSlabPolynomial.Sign(ref root,
 538        System.Diagnostics.Debug.Assert(denominatorSign != 0);
 1593539        if (sign == 0) return true;
 613540        sign *= denominatorSign;
 613541        ulong limit = sign < 0 ? 1UL << 63 : long.MaxValue;
 1226542        ulong lower = 0, upper = limit;
 613543        if (TryGetRatioFloorBounds(ref root, numerator, denominator, sign * denominatorSign,
 613544                denominatorSign, limit, false, out ulong minimum, out ulong maximum))
 1202545        { lower = minimum; upper = maximum; }
 2851546        while (lower < upper)
 547        {
 2238548            ulong mid = lower + ((upper - lower) >> 1) + 1;
 6714549            scalar.Clear(); scalar.Values[0] = mid; scalar.Signs[0] = (sbyte)denominatorSign;
 8952550            term.Multiply(denominator, scalar); query.Clear(); query.Add(numerator, sign * denominatorSign); query.Add(t
 4476551            if (FiniteSlabPolynomial.Sign(ref root, query) >= 0) lower = mid; else upper = mid - 1;
 552        }
 1839553        scalar.Clear(); scalar.Values[0] = lower; scalar.Signs[0] = (sbyte)denominatorSign;
 2452554        term.Multiply(denominator, scalar); query.Clear(); query.Add(numerator, sign * denominatorSign * 2); query.Add(t
 613555        query.Add(denominator, -denominatorSign);
 613556        int halfway = FiniteSlabPolynomial.Sign(ref root, query);
 613557        ulong rounded = lower + (halfway > 0 || halfway == 0
 613558            && ((lower ^ unchecked((ulong)parityOffset)) & 1) != 0 ? 1UL : 0);
 615559        if (rounded > limit) return false;
 1222560        value = Fixed64.FromRaw(sign < 0 ? unchecked(-(long)rounded) : (long)rounded); return true;
 561    }
 562
 563    /// <summary>
 564    /// Bounds the final nonnegative ratio using the existing certified Horner
 565    /// intervals. These bounds only narrow the exact nearest-even search;
 566    /// cancellation or a vanishing denominator retains its full-range path.
 567    /// </summary>
 568    private static bool TryGetRatioFloorBounds(scoped ref FiniteAxisValueRoot root,
 569        scoped FiniteSlabPolynomial numerator, scoped FiniteSlabPolynomial denominator,
 570        int numeratorSign, int denominatorSign, ulong limit, bool squareRoot,
 571        out ulong minimum, out ulong maximum)
 572    {
 805573        int Words = numerator.FieldWords;
 1610574        minimum = 0; maximum = limit;
 575        const int precision = 59;
 576        // At most nine coefficients: 59 + 2*ceil(log2(9)) <= 67.
 805577        WideFiniteAxisIntersection.RefineFiniteValueRoot(ref root, 70);
 805578        Span<sbyte> signs = stackalloc sbyte[numerator.Count + denominator.Count];
 1610579        int numeratorBits = 0, denominatorBits = 0;
 11178580        for (int index = 0; index < numerator.Count; index++)
 581        {
 4784582            signs[index] = (sbyte)(numerator.Signs[index] * numeratorSign);
 4784583            numeratorBits = Math.Max(numeratorBits, WideArithmetic.GetMagnitudeBitLength(
 4784584                numerator.Values.Slice(index * Words, Words)));
 585        }
 9708586        for (int index = 0; index < denominator.Count; index++)
 587        {
 4049588            signs[numerator.Count + index] = (sbyte)(denominator.Signs[index] * denominatorSign);
 4049589            denominatorBits = Math.Max(denominatorBits, WideArithmetic.GetMagnitudeBitLength(
 4049590                denominator.Values.Slice(index * Words, Words)));
 591        }
 805592        WideFiniteAxisIntersection.GetFiniteValueRootNonnegativeBounds(root, numerator.Values,
 805593            signs[..numerator.Count], precision, numeratorBits, out ulong nMin, out ulong nMax);
 805594        WideFiniteAxisIntersection.GetFiniteValueRootNonnegativeBounds(root, denominator.Values,
 805595            signs[numerator.Count..], precision, denominatorBits, out ulong dMin, out ulong dMax);
 819596        if (dMin == 0) return false;
 791597        int shift = numeratorBits - denominatorBits;
 791598        int words = (Math.Abs(shift) + 127) / 64;
 791599        Span<ulong> bank = stackalloc ulong[2 * words];
 1582600        Span<ulong> n = bank[..words], d = bank[words..];
 791601        Span<ulong> endpoints = stackalloc ulong[4] { nMin, nMax, dMin, dMax };
 4746602        for (int bound = 0; bound < 2; bound++)
 603        {
 6328604            n.Clear(); d.Clear(); int ns = 0, ds = 0;
 1582605            WideArithmetic.AddShiftedSignedMagnitude(endpoints.Slice(bound, 1), 1, Math.Max(0, shift), n, ref ns);
 1582606            WideArithmetic.AddShiftedSignedMagnitude(endpoints.Slice(3 - bound, 1), 1, Math.Max(0, -shift), d, ref ds);
 607            ulong value;
 1962608            if (squareRoot) value = WideArithmetic.GetRatioFloorSquareRoot(n, d, limit);
 609            else
 610            {
 611                // Negative raw ratios admit the full unsigned 2^63 magnitude.
 612                // Expand nearest-even endpoint rounding by one integer so it
 613                // remains a conservative bound on the exact ratio's floor.
 1202614                value = Fixed64.TryGetSignedRawRatio(n, d, true, out Fixed64 rounded)
 1202615                    ? unchecked((ulong)(-rounded.m_rawValue)) : limit;
 1202616                value = Math.Min(value, limit);
 1803617                if (bound == 0) value = value == 0 ? 0 : value - 1;
 1192618                else if (value < limit) value++;
 619            }
 3164620            if (bound == 0) minimum = value; else maximum = value;
 621        }
 791622        return true;
 623    }
 624
 625    private static bool IsConstant(FiniteSlabPolynomial value)
 626    {
 9239627        int Words = value.FieldWords;
 90188628        for (int index = 1; index < value.Count; index++) if (value.Signs[index] != 0) return false;
 7944629        return true;
 630    }
 631
 6681632    private static Signed320 Component(WideAxis3 p, int axis) => axis == 0 ? p.X : axis == 1 ? p.Y : p.Z;
 2188633    private static Signed576 Component(WideDirection3d p, int axis) => axis == 0 ? p.X : axis == 1 ? p.Y : p.Z;
 2073634    private static Signed576 Signed(Signed576 value, int sign) => sign < 0 ? WideArithmetic.SubtractSigned576(default, v
 21635    private static Signed320 Signed(Signed320 value, int sign) => sign < 0 ? WideArithmetic.Negate(value) : value;
 1468636    private static WideAxis3 Difference(WideAxis3 p, WideAxis3 q) => new(
 1468637        WideArithmetic.SubtractSigned320(p.X, q.X), WideArithmetic.SubtractSigned320(p.Y, q.Y),
 1468638        WideArithmetic.SubtractSigned320(p.Z, q.Z));
 639}

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

#LineLine coverage
 1//=======================================================================
 2// FiniteSlabRaySelection.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/// <content>Retains native point fields from the same quadratic active-set root used for selection.</content>
 13internal ref partial struct FiniteSlabRaySelection
 14{
 15    internal readonly int CompareNativeDepth(in CurvedPrismContactGeometry geometry, in FiniteSlabRayFrame frame,
 16        scoped CurvedPrismContactValue native)
 17    {
 1218        if (!native.HasValue) return -1;
 819        int axis = !frame.Plane.Normal.X.IsZero ? 0 : !frame.Plane.Normal.Y.IsZero ? 1 : 2;
 820        int words = DepthCoefficientWords() + 6;
 1621        Span<ulong> values = stackalloc ulong[4 * words], root = stackalloc ulong[2 * words + 1];
 822        Span<int> signs = stackalloc int[4];
 1623        var n = ContactQuadratic.At(values, signs, 0, words); var d = ContactQuadratic.At(values, signs, 1, words);
 824        GetPhysicalDepthRatio(frame, axis, root, n, d);
 25        // The ratio is the selected coordinate displacement. Its component
 26        // metric restores the full physical length, without rounding t.
 827        return native.CompareRootRatio(geometry, n, d, root, frame.Plane.NormalSquared,
 828            Signed320.NarrowValue(axis == 0 ? frame.Plane.Normal.X : axis == 1 ? frame.Plane.Normal.Y : frame.Plane.Norm
 29    }
 30
 31    // The defining equations have at most three coefficients. Degree-nine
 32    // polynomials elsewhere only test admission; they never define this root.
 33    private readonly void GetRootParameter(scoped Span<ulong> radical,
 34        scoped ContactQuadratic numerator, scoped ContactQuadratic denominator)
 35    {
 4036        radical.Clear();
 4037        int words = numerator.FieldWords;
 8038        Span<ulong> values = stackalloc ulong[6 * words]; Span<int> signs = stackalloc int[6];
 4039        var a = ContactQuadratic.At(values, signs, 0, words);
 4040        var b = ContactQuadratic.At(values, signs, 1, words);
 4041        var c = ContactQuadratic.At(values, signs, 2, words);
 8042        CopyDepthCoefficient(Polynomial, 2, a); a.Add(a);
 4043        CopyDepthCoefficient(Polynomial, 1, b);
 8044        CopyDepthCoefficient(Polynomial, 0, c); c.Add(c);
 4045        int branch = 1;
 4046        if (a.Signs[0] != 0)
 47        {
 6648            Span<ulong> cell = stackalloc ulong[CellWords]; FiniteAxisValueRoot root = Restore(cell);
 6649            Span<ulong> derivativeValues = stackalloc ulong[2 * Words]; Span<sbyte> derivativeSigns = stackalloc sbyte[2
 3350            FiniteSlabPolynomial derivative = new(derivativeValues, derivativeSigns);
 9951            derivative.Clear(); derivative.Add(Polynomial.Slice(1, 1)); derivative.Add(Polynomial.Slice(2, 1), 2, 1);
 3352            int derivativeSign = FiniteSlabPolynomial.Sign(ref root, derivative);
 6453            if (derivativeSign != 0) branch = derivativeSign * a.Signs[0];
 54        }
 4055        bool represented = ContactQuadratic.TryGetParameter(a, b, c, branch, radical, numerator, denominator);
 56        System.Diagnostics.Debug.Assert(represented);
 4057    }
 58
 59    internal readonly void GetNativeLinePointFields(in FiniteSlabRayFrame frame, in WideAxis3 a,
 60        in WideAxis3 e, Span<ulong> source, Span<int> sourceSigns,
 61        Span<ulong> exit, Span<int> exitSigns, scoped ContactQuadratic denominator, scoped Span<ulong> radical)
 62    {
 1763        int words = denominator.FieldWords;
 3464        Span<ulong> values = stackalloc ulong[14 * words]; Span<int> signs = stackalloc int[14];
 3465        var uN = ContactQuadratic.At(values, signs, 0, words); var uD = ContactQuadratic.At(values, signs, 1, words);
 1766        var l = ContactQuadratic.At(values, signs, 2, words);
 3467        var t = ContactQuadratic.At(values, signs, 3, words); var coefficient = ContactQuadratic.At(values, signs, 4, wo
 3468        var term = ContactQuadratic.At(values, signs, 5, words); var product = ContactQuadratic.At(values, signs, 6, wor
 1769        GetRootParameter(radical, uN, uD);
 1770        Evaluate(Lambda, uN, uD, radical, l, coefficient, product);
 1771        Evaluate(T, uN, uD, radical, t, coefficient, product);
 1772        Evaluate(D, uN, uD, radical, denominator, coefficient, product);
 13673        for (int axis = 0; axis < 3; axis++)
 74        {
 5175            var point = ContactQuadratic.At(source, sourceSigns, axis, words);
 5176            ContactQuadratic.Scale(denominator, Signed576.ExtendValue(Component(a, axis)), point);
 10277            ContactQuadratic.Scale(l, Signed576.ExtendValue(Component(e, axis)), term); point.Add(term);
 10278            var moved = ContactQuadratic.At(exit, exitSigns, axis, words); point.CopyTo(moved);
 10279            ContactQuadratic.Scale(t, Component(frame.RayNormal, axis), term); moved.Add(term);
 80        }
 1781        if (denominator.Sign(radical) < 0)
 82        {
 783            denominator.MultiplySign(-1);
 5684            for (int axis = 0; axis < 3; axis++)
 85            {
 2186                ContactQuadratic.At(source, sourceSigns, axis, words).MultiplySign(-1);
 2187                ContactQuadratic.At(exit, exitSigns, axis, words).MultiplySign(-1);
 88            }
 89        }
 1790    }
 91
 92    private static void Evaluate(scoped FiniteSlabPolynomial polynomial, scoped ContactQuadratic uN,
 93        scoped ContactQuadratic uD, ReadOnlySpan<ulong> radical, scoped ContactQuadratic result,
 94        scoped ContactQuadratic coefficient, scoped ContactQuadratic term)
 95    {
 5196        CopyDepthCoefficient(polynomial, 0, coefficient);
 5197        ContactQuadratic.Multiply(coefficient, uD, radical, result);
 98        System.Diagnostics.Debug.Assert(polynomial.Count == 2);
 5199        CopyDepthCoefficient(polynomial, 1, coefficient);
 102100        ContactQuadratic.Multiply(coefficient, uN, radical, term); result.Add(term);
 51101    }
 102}

Methods/Properties

get_Words()
GetStorageWords(System.Int32)
get_Polynomial()
get_Lambda()
get_Mu()
get_T()
get_D()
get_DepthN()
get_DepthD()
get_RetainedCell()
At(System.Int32,System.Int32)
.ctor(System.Span`1<System.UInt64>,System.Span`1<System.SByte>,System.Int32)
Restore(System.Span`1<System.UInt64>)
get_CellWords()
get_Metadata()
Restore(FixedMathSharp.Geometry.FiniteSlabRaySelectionMetadata)
CompareDepth(FixedMathSharp.Geometry.FiniteSlabRaySelection&)
CompareDepthAcrossFrames(FixedMathSharp.Geometry.FiniteSlabRaySelection&,FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.FiniteSlabRayFrame&)
DepthCoefficientWords()
GetPhysicalDepthRatio(FixedMathSharp.Geometry.FiniteSlabRayFrame&,System.Int32,System.Span`1<System.UInt64>,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic)
CopyDepthCoefficient(FixedMathSharp.Geometry.FiniteSlabPolynomial,System.Int32,FixedMathSharp.Geometry.ContactQuadratic)
Compare(System.Boolean,FixedMathSharp.Geometry.FiniteAxisValueRoot,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,System.Boolean,FixedMathSharp.Geometry.FiniteAxisValueRoot,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial)
Keep(FixedMathSharp.Geometry.FiniteAxisValueRoot,System.Int32,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,System.Boolean,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FixedTriangle,System.Int32,System.Int32)
BuildAuthoredCoordinate(System.Int32,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial)
ContainsTrianglePoint(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.FixedTriangle,FixedMathSharp.Geometry.FiniteSlabRayFrame&)
TryGetSourcePointInSamplingFrame(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Vector3d&)
TryGetContactAnchor(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Fixed64&,System.Boolean&,FixedMathSharp.Vector3d&,FixedMathSharp.Geometry.FixedPointAnchor&)
GetDepth(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Fixed64&,System.Boolean&)
GetRoundedDepth(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.FiniteAxisValueRoot&,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Fixed64&,System.Boolean&)
CompareDepth(FixedMathSharp.Geometry.FiniteAxisValueRoot&,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,System.UInt64)
TryRoundRatio(FixedMathSharp.Geometry.FiniteAxisValueRoot&,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Fixed64&,System.Int64)
TryGetRatioFloorBounds(FixedMathSharp.Geometry.FiniteAxisValueRoot&,FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.FiniteSlabPolynomial,System.Int32,System.Int32,System.UInt64,System.Boolean,System.UInt64&,System.UInt64&)
IsConstant(FixedMathSharp.Geometry.FiniteSlabPolynomial)
Component(FixedMathSharp.Geometry.WideAxis3,System.Int32)
Component(FixedMathSharp.Geometry.WideDirection3d,System.Int32)
Signed(FixedMathSharp.Signed576,System.Int32)
Signed(FixedMathSharp.Signed320,System.Int32)
Difference(FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideAxis3)
CompareNativeDepth(FixedMathSharp.Geometry.CurvedPrismContactGeometry&,FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.CurvedPrismContactValue)
GetRootParameter(System.Span`1<System.UInt64>,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic)
GetNativeLinePointFields(FixedMathSharp.Geometry.FiniteSlabRayFrame&,FixedMathSharp.Geometry.WideAxis3&,FixedMathSharp.Geometry.WideAxis3&,System.Span`1<System.UInt64>,System.Span`1<System.Int32>,System.Span`1<System.UInt64>,System.Span`1<System.Int32>,FixedMathSharp.Geometry.ContactQuadratic,System.Span`1<System.UInt64>)
Evaluate(FixedMathSharp.Geometry.FiniteSlabPolynomial,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,System.ReadOnlySpan`1<System.UInt64>,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic,FixedMathSharp.Geometry.ContactQuadratic)