< Summary

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

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Root()100%11100%
get_Point()100%11100%
.ctor(...)100%44100%
Keep(...)100%1818100%
KeepEvaluated(...)100%22100%
Restore(...)100%11100%
TryMaterialize(...)100%11100%
TryMaterialize(...)100%1010100%
TryGetRoundedMaximumDepth(...)100%22100%
GetRoundedMaximumDepth()100%44100%
CompareDepth(...)100%88100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// ConePlaneRaySelection.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2024-present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using System;
 9
 10namespace FixedMathSharp.Geometry;
 11
 12/// <summary>Caller-owned storage for an admitted, unrounded plane-ray maximum.</summary>
 13internal ref struct ConePlaneRaySelection
 14{
 15    internal const int FieldWords = 64;
 16    internal const int RootWords = 40;
 17    internal const int StorageWords = 4 * FieldWords + RootWords + ConePlaneRayPoint.StorageWords;
 18    internal const int SignCount = 4 + ConePlaneRayPoint.SignCount;
 19    internal readonly Span<ulong> Values;
 20    internal readonly Span<int> Signs;
 21    internal bool HasValue;
 22    internal ConePlaneRayEvent CurrentEvent, MaximumEvent;
 23    internal ConePlaneRayEventSource CurrentSource, MaximumSource;
 24    private Signed832 metric;
 25    private Signed320 scale;
 26    private readonly int _fieldWords, _rootWords;
 2076927    internal ReadOnlySpan<ulong> Root => Values.Slice(4 * _fieldWords, _rootWords);
 2395828    internal ConePlaneRayPoint Point => new(Values[(4 * _fieldWords + _rootWords)..], Signs[4..], _fieldWords);
 29
 30    internal ConePlaneRaySelection(Span<ulong> values, Span<int> signs,
 31        int fieldWords = FieldWords, int rootWords = RootWords)
 32    {
 11366633        int storageWords = 12 * fieldWords + rootWords;
 11366634        if (values.Length < storageWords || signs.Length < SignCount)
 235            throw new ArgumentException("The plane-ray selection storage is too small.");
 34099236        Values = values[..storageWords]; Signs = signs[..SignCount]; HasValue = false;
 22732837        _fieldWords = fieldWords; _rootWords = rootWords;
 11366438        CurrentEvent = MaximumEvent = default;
 11366439        CurrentSource = MaximumSource = default;
 22732840        metric = default; scale = default;
 11366441    }
 42
 43    internal bool Keep(scoped ContactQuadratic numerator, scoped ContactQuadratic denominator, scoped ReadOnlySpan<ulong
 44        in ConePlaneRayFrame frame, scoped ConePlaneRayPoint point)
 45    {
 1547046        if (numerator.Sign(root) < 0 || denominator.Sign(root) <= 0)
 247            throw new ArgumentException("The admitted depth must be nonnegative with a positive denominator.");
 1546848        ContactQuadratic bestN = ContactQuadratic.At(Values, Signs, 0, _fieldWords);
 1546849        ContactQuadratic bestD = ContactQuadratic.At(Values, Signs, 1, _fieldWords);
 1546850        if (HasValue)
 51        {
 581152            int comparison = ContactQuadratic.CompareRatios(numerator, denominator, root, bestN, bestD, Root);
 581153            int pointOrder = comparison == 0 ? point.CompareTo(Point, root, Root) : 0;
 581154            if (comparison < 0 || comparison == 0 && (pointOrder > 0 || pointOrder == 0
 581155                    && ConePlaneRayEvents.CompareCoincidentProvenance(CurrentSource, CurrentEvent, MaximumSource, Maximu
 377556                return false;
 57        }
 2338658        numerator.CopyTo(bestN); denominator.CopyTo(bestD);
 1169359        Span<ulong> retainedRoot = Values.Slice(4 * _fieldWords, _rootWords);
 2338660        root.CopyTo(retainedRoot); retainedRoot[root.Length..].Clear();
 1169361        metric = frame.NormalSquared;
 1169362        scale = WideArithmetic.AddSigned320(frame.Finite.ShapeFrame.CoordinateDenominator, frame.Finite.ShapeFrame.Coord
 1169363        HasValue = true;
 1169364        MaximumEvent = CurrentEvent;
 1169365        MaximumSource = CurrentSource;
 66        // Rational points have zero radical coefficients, so the exit's root
 67        // also represents them. Side and certified exits already share the
 68        // point field. Retain only the winning point, never a wide event pool.
 1169369        point.CopyTo(Point);
 1169370        return true;
 71    }
 72
 73    internal bool KeepEvaluated(scoped in ConePlaneRaySelection other, in ConePlaneRayFrame frame)
 74    {
 909475        if (!other.HasValue) return false;
 1305676        CurrentSource = other.MaximumSource; CurrentEvent = other.MaximumEvent;
 652877        return Keep(ContactQuadratic.At(other.Values, other.Signs, 0, other._fieldWords),
 652878            ContactQuadratic.At(other.Values, other.Signs, 1, other._fieldWords), other.Root, frame, other.Point);
 79    }
 80
 81    /// <summary>Restores metadata after reborrowing previously populated winning coefficient/sign storage.</summary>
 82    internal void Restore(in ConePlaneRayFrame frame, in ConePlaneRayEventSource source, ConePlaneRayEvent descriptor)
 83    {
 904584        metric = frame.NormalSquared;
 904585        scale = WideArithmetic.AddSigned320(frame.Finite.ShapeFrame.CoordinateDenominator, frame.Finite.ShapeFrame.Coord
 2713586        CurrentSource = MaximumSource = source; CurrentEvent = MaximumEvent = descriptor; HasValue = true;
 904587    }
 88
 89    internal bool TryMaterialize(in ConePlaneRayFrame frame, int orientation,
 90        out Vector3d lower, out Vector3d upper, out Fixed64 depth)
 160091        => TryMaterialize(frame, orientation, Vector3d.Zero, out lower, out upper, out depth);
 92
 93    internal bool TryMaterialize(in ConePlaneRayFrame frame, int orientation, Vector3d samplingOrigin,
 94        out Vector3d lower, out Vector3d upper, out Fixed64 depth)
 95    {
 324896        lower = upper = default; depth = default;
 162597        if (orientation != 1 && orientation != -1) throw new ArgumentOutOfRangeException(nameof(orientation));
 162398        return HasValue && ConePlaneRayPointMaterialization.TryGetPointInFrame(frame, Point, Root, samplingOrigin, out l
 162399            && TryGetRoundedMaximumDepth(out depth)
 1623100            && ConePlaneRayPointMaterialization.TryGetExitPointInFrame(frame, Point, Root,
 1623101                ContactQuadratic.At(Values, Signs, 0, _fieldWords), ContactQuadratic.At(Values, Signs, 1, _fieldWords), 
 102    }
 103
 104    internal bool TryGetRoundedMaximumDepth(out Fixed64 depth)
 105    {
 1714106        depth = Fixed64.Zero;
 1714107        if (!HasValue)
 4108            return false;
 1710109        Span<ulong> metricWords = stackalloc ulong[13];
 1710110        WideArithmetic.GetMagnitude(metric, metricWords);
 1710111        Span<ulong> scaleWords = stackalloc ulong[5];
 1710112        WideArithmetic.GetMagnitude(scale, out scaleWords[4], out scaleWords[3], out scaleWords[2], out scaleWords[1], o
 1710113        return ContactQuadratic.TryRoundRootRatio(ContactQuadratic.At(Values, Signs, 0, _fieldWords),
 1710114            ContactQuadratic.At(Values, Signs, 1, _fieldWords), Root, metricWords, scaleWords, out depth);
 115    }
 116
 117    internal Fixed64 GetRoundedMaximumDepth()
 118    {
 121119        if (!HasValue)
 1120            throw new InvalidOperationException("The plane-ray selection has no admitted value.");
 120121        if (!TryGetRoundedMaximumDepth(out Fixed64 depth))
 1122            throw new OverflowException("The exact plane-ray maximum is outside the Fixed64 range.");
 119123        return depth;
 124    }
 125
 126    /// <summary>Compares physical depths across certified coplanar members in the same cone chart.</summary>
 127    /// <remarks>Member coordinate denominators may differ; the reduced normal metric must agree.</remarks>
 128    internal int CompareDepth(scoped in ConePlaneRaySelection other)
 129    {
 39130        if (!HasValue || !other.HasValue)
 2131            throw new InvalidOperationException("Both plane-ray selections must have an admitted value.");
 37132        if (metric.IsZero || !metric.Equals(other.metric))
 2133            throw new ArgumentException("The plane-ray selections must share a nonzero reduced normal metric.");
 35134        ContactQuadratic firstD = ContactQuadratic.At(Values, Signs, 1, _fieldWords);
 35135        ContactQuadratic secondD = ContactQuadratic.At(other.Values, other.Signs, 1, other._fieldWords);
 136        // sqrt(metric) cancels. Each positive 2D scale adds at most three limbs;
 137        // the ratio owner's subsequent cross products reserve their full widths.
 35138        int words = Math.Max(ContactQuadratic.ActiveWords(firstD), ContactQuadratic.ActiveWords(secondD)) + 5;
 70139        Span<ulong> values = stackalloc ulong[4 * words]; Span<int> signs = stackalloc int[4];
 35140        ContactQuadratic firstScaled = ContactQuadratic.At(values, signs, 0, words);
 35141        ContactQuadratic secondScaled = ContactQuadratic.At(values, signs, 1, words);
 35142        ContactQuadratic.Scale(firstD, Signed576.ExtendValue(scale), firstScaled);
 35143        ContactQuadratic.Scale(secondD, Signed576.ExtendValue(other.scale), secondScaled);
 35144        return ContactQuadratic.CompareRatios(ContactQuadratic.At(Values, Signs, 0, _fieldWords), firstScaled, Root,
 35145            ContactQuadratic.At(other.Values, other.Signs, 0, other._fieldWords), secondScaled, other.Root);
 146    }
 147}