< Summary

Information
Class: FixedMathSharp.Geometry.CylinderContactAlgebra
Assembly: FixedMathSharp
File(s): /home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Wide/Convex/CylinderContactAlgebra.cs
Line coverage
100%
Covered lines: 119
Uncovered lines: 0
Coverable lines: 119
Total lines: 202
Line coverage: 100%
Branch coverage
100%
Covered branches: 36
Total branches: 36
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
BuildQuadraticCandidate(...)100%22100%
BuildRadialCandidate(...)100%66100%
WriteWorldDirection(...)100%66100%
Dot(...)100%22100%
Dot(...)100%22100%
ProjectPerpendicular(...)100%22100%
SumSquares(...)100%22100%
ProjectPerpendicular(...)100%22100%
WriteDirection(...)100%22100%
WriteDirection(...)100%22100%
Add(...)100%11100%
IsZero(...)100%11100%
Slot(...)100%11100%
Slot(...)100%11100%
Slot(...)100%11100%
Slot(...)100%11100%
Import(...)100%11100%
Import(...)100%11100%
Import(...)100%11100%
DifferenceOfProducts(...)100%11100%
Component(...)100%44100%
Component(...)100%44100%
Axis(...)100%11100%

File(s)

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Wide/Convex/CylinderContactAlgebra.cs

#LineLine coverage
 1//=======================================================================
 2// CylinderContactAlgebra.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>Shared exact radial support-candidate encoding for finite cylinders.</summary>
 13internal static class CylinderContactAlgebra
 14{
 15    internal const int Words = ConvexContactCandidate.Words;
 16
 17    /// <summary>Encodes a signed quadratic numerator over a positive square-root denominator.</summary>
 18    internal static int BuildQuadraticCandidate(ContactQuadratic numerator, ReadOnlySpan<ulong> root,
 19        ReadOnlySpan<ulong> denominator, Span<ulong> values, Span<int> signs)
 20    {
 21        // (A+B*sqrt(K))²=(A²+B²K)+2AB*sqrt(K). Squaring needs one
 22        // cross-product; its rational coefficient is always nonnegative.
 182423        Span<ulong> product = stackalloc ulong[Words];
 364824        Span<ulong> rational = Slot(values, 7), radical = Slot(values, 8);
 182425        WideArithmetic.MultiplyMagnitudes(numerator.Rational, numerator.Rational, rational);
 182426        WideArithmetic.MultiplyMagnitudes(numerator.Radical, numerator.Radical, product);
 182427        WideArithmetic.MultiplyMagnitudes(product, root, radical);
 182428        WideArithmetic.AddMagnitudeInto(radical, rational);
 182429        WideArithmetic.MultiplyMagnitudes(numerator.Rational, numerator.Radical, radical);
 182430        WideArithmetic.AddMagnitudeInto(radical, radical);
 364831        root.CopyTo(Slot(values, 9)); denominator.CopyTo(Slot(values, 10));
 182432        signs[7] = IsZero(rational) ? 0 : 1;
 182433        signs[8] = IsZero(radical) ? 0 : numerator.Signs[0] * numerator.Signs[1];
 182434        return numerator.Sign(root);
 35    }
 36
 37    /// <summary>Encodes (p+sqrt(q))/sqrt(d), including its signed gap, at the input field stride.</summary>
 38    // q/d may borrow output slots9/10; consume them before overwriting either slot.
 39    internal static int BuildRadialCandidate(ReadOnlySpan<ulong> p, int pSign,
 40        ReadOnlySpan<ulong> q, ReadOnlySpan<ulong> d, Span<ulong> values, Span<int> signs)
 41    {
 6758942        int words = p.Length;
 6758943        Span<ulong> squared = stackalloc ulong[words];
 6758944        WideArithmetic.MultiplyMagnitudes(p, p, squared);
 6758945        WideArithmetic.AddEqualMagnitudes(squared, q, Slot(values, 7, words));
 6758946        WideArithmetic.AddEqualMagnitudes(p, p, Slot(values, 8, words));
 6758947        q.CopyTo(Slot(values, 9, words));
 6758948        d.CopyTo(Slot(values, 10, words));
 6758949        signs[7] = IsZero(Slot(values, 7, words)) ? 0 : 1;
 6758950        signs[8] = pSign;
 6758951        return pSign < 0 ? WideArithmetic.CompareMagnitudeEqualLength(q, squared)
 6758952            : pSign > 0 || !IsZero(q) ? 1 : 0;
 53    }
 54
 55    internal static void WriteWorldDirection(WideRationalBasis3d basis,
 56        ReadOnlySpan<ulong> direction, ReadOnlySpan<int> directionSigns,
 57        Span<ulong> values, Span<int> signs, int orientation = 1)
 58    {
 5116759        int Words = direction.Length / 3;
 40933660        for (int component = 0; component < 3; component++)
 61        {
 15350162            WideAxis3 row = component == 0 ? Axis(basis.Xx, basis.Yx, basis.Zx)
 15350163                : component == 1 ? Axis(basis.Xy, basis.Yy, basis.Zy) : Axis(basis.Xz, basis.Yz, basis.Zz);
 15350164            Dot(row, direction, directionSigns, Slot(values, component, Words), out int sign);
 15350165            signs[component] = orientation * sign;
 66        }
 5116767    }
 68
 69    internal static void Dot(WideAxis3 axis, ReadOnlySpan<ulong> direction, ReadOnlySpan<int> signs,
 70        Span<ulong> result, out int sign)
 71    {
 29020572        int Words = result.Length;
 29020573        Span<ulong> component = stackalloc ulong[Words];
 29020574        Span<ulong> product = stackalloc ulong[Words];
 58041075        result.Clear(); sign = 0;
 232164076        for (int index = 0; index < 3; index++)
 77        {
 87061578            Signed320 value = Component(axis, index);
 87061579            Import(value, component);
 87061580            WideArithmetic.MultiplyMagnitudes(component, Slot(direction, index, Words), product);
 87061581            Add(product, value.Sign * signs[index], result, ref sign);
 82        }
 29020583    }
 84
 85    internal static void Dot(in WideDirection3d axis, ReadOnlySpan<ulong> direction, ReadOnlySpan<int> signs,
 86        Span<ulong> result, out int sign)
 87    {
 65133788        int Words = result.Length;
 130267489        Span<ulong> component = stackalloc ulong[Words], product = stackalloc ulong[Words];
 130267490        result.Clear(); sign = 0;
 521069691        for (int index = 0; index < 3; index++)
 92        {
 195401193            Signed576 value = Component(axis, index);
 195401194            Import(value, component);
 195401195            WideArithmetic.MultiplyMagnitudes(component, Slot(direction, index, Words), product);
 195401196            Add(product, value.Sign * signs[index], result, ref sign);
 97        }
 65133798    }
 99
 100    internal static void ProjectPerpendicular(WideAxis3 axis, WideAxis3 value,
 101        Span<ulong> direction, Span<int> signs)
 102    {
 14287103        Span<ulong> work = stackalloc ulong[4 * Words];
 57148104        Span<ulong> u = Slot(work, 0), dot = Slot(work, 1), component = Slot(work, 2), product = Slot(work, 3);
 14287105        Import(axis.SquaredLength, u);
 14287106        Signed576 projection = WideAxis3.Dot(axis, value);
 14287107        Import(projection, dot);
 114296108        for (int index = 0; index < 3; index++)
 109        {
 42861110            Signed320 v = Component(value, index);
 42861111            Signed320 a = Component(axis, index);
 42861112            Import(v, component);
 42861113            WideArithmetic.MultiplyMagnitudes(u, component, Slot(direction, index));
 42861114            int sign = v.Sign;
 42861115            Import(a, component);
 42861116            WideArithmetic.MultiplyMagnitudes(dot, component, product);
 42861117            Add(product, -projection.Sign * a.Sign, Slot(direction, index), ref sign);
 42861118            signs[index] = sign;
 119        }
 14287120    }
 121
 122    internal static void SumSquares(ReadOnlySpan<ulong> direction, Span<ulong> result)
 123    {
 104405124        int Words = result.Length;
 104405125        Span<ulong> product = stackalloc ulong[Words];
 104405126        result.Clear();
 835240127        for (int index = 0; index < 3; index++)
 128        {
 313215129            ReadOnlySpan<ulong> component = Slot(direction, index, Words);
 313215130            WideArithmetic.MultiplyMagnitudes(component, component, product);
 313215131            WideArithmetic.AddMagnitudeInto(product, result);
 132        }
 104405133    }
 134
 135    internal static void ProjectPerpendicular(in WideDirection3d axis, in WideDirection3d value,
 136        Span<ulong> direction, Span<int> signs)
 137    {
 13358138        Span<ulong> work = stackalloc ulong[4 * Words];
 53432139        Span<ulong> norm = Slot(work, 0), dot = Slot(work, 1), component = Slot(work, 2), product = Slot(work, 3);
 13358140        Import(axis.SquaredLength, norm);
 13358141        Signed832 projection = WideDirection3d.Dot(axis, value);
 13358142        Import(projection, dot);
 106864143        for (int index = 0; index < 3; index++)
 144        {
 80148145            Signed576 v = Component(value, index), a = Component(axis, index);
 40074146            Import(v, component);
 40074147            WideArithmetic.MultiplyMagnitudes(norm, component, Slot(direction, index));
 40074148            int sign = v.Sign;
 40074149            Import(a, component);
 40074150            WideArithmetic.MultiplyMagnitudes(dot, component, product);
 40074151            Add(product, -projection.Sign * a.Sign, Slot(direction, index), ref sign);
 40074152            signs[index] = sign;
 153        }
 13358154    }
 155
 156    internal static void WriteDirection(WideAxis3 axis, Span<ulong> direction, Span<int> signs)
 157    {
 9915158        int Words = direction.Length / 3;
 79320159        for (int index = 0; index < 3; index++)
 160        {
 29745161            Signed320 value = Component(axis, index);
 59490162            Import(value, Slot(direction, index, Words)); signs[index] = value.Sign;
 163        }
 9915164    }
 165    internal static void WriteDirection(in WideDirection3d axis, Span<ulong> direction, Span<int> signs)
 166    {
 52910167        int Words = direction.Length / 3;
 423280168        for (int index = 0; index < 3; index++)
 169        {
 158730170            Signed576 value = Component(axis, index);
 317460171            Import(value, Slot(direction, index, Words)); signs[index] = value.Sign;
 172        }
 52910173    }
 174
 175    internal static void Add(ReadOnlySpan<ulong> value, int sign, Span<ulong> destination, ref int destinationSign) =>
 5949188176        WideArithmetic.AddShiftedSignedMagnitude(value, sign, 0, destination, ref destinationSign);
 1776685177    internal static bool IsZero(ReadOnlySpan<ulong> value) => WideArithmetic.GetActiveMagnitudeLength(value) == 0;
 1629945178    internal static Span<ulong> Slot(Span<ulong> values, int index) => values.Slice(index * Words, Words);
 457155179    internal static ReadOnlySpan<ulong> Slot(ReadOnlySpan<ulong> values, int index) => values.Slice(index * Words, Words
 984643180    internal static Span<ulong> Slot(Span<ulong> values, int index, int words) => values.Slice(index * words, words);
 3139055181    internal static ReadOnlySpan<ulong> Slot(ReadOnlySpan<ulong> values, int index, int words) => values.Slice(index * w
 1306361182    internal static void Import(Signed320 value, Span<ulong> result) => Import(Signed576.ExtendValue(value), result);
 4902772183    internal static void Import(Signed576 value, Span<ulong> result) => WideArithmetic.GetMagnitude(value, result);
 128844184    internal static void Import(Signed832 value, Span<ulong> result) => WideArithmetic.GetMagnitude(value, result);
 185    internal static void DifferenceOfProducts(Signed832 a, Signed832 b, Signed832 c, Signed832 d,
 186        Span<ulong> result, out int sign)
 187    {
 2691188        Span<ulong> left = stackalloc ulong[13], right = stackalloc ulong[13], product = stackalloc ulong[result.Length]
 1794189        WideArithmetic.GetMagnitude(a, left); WideArithmetic.GetMagnitude(b, right);
 897190        WideArithmetic.MultiplyMagnitudes(left, right, result);
 897191        sign = a.Sign * b.Sign;
 1794192        WideArithmetic.GetMagnitude(c, left); WideArithmetic.GetMagnitude(d, right);
 897193        WideArithmetic.MultiplyMagnitudes(left, right, product);
 897194        Add(product, -c.Sign * d.Sign, result, ref sign);
 897195    }
 196    internal static Signed320 Component(in WideAxis3 value, int index) =>
 989250197        index == 0 ? value.X : index == 1 ? value.Y : value.Z;
 198    internal static Signed576 Component(in WideDirection3d value, int index) =>
 2477085199        index == 0 ? value.X : index == 1 ? value.Y : value.Z;
 153501200    private static WideAxis3 Axis(Signed192 x, Signed192 y, Signed192 z) => new(
 153501201        Signed320.ExtendValue(x), Signed320.ExtendValue(y), Signed320.ExtendValue(z));
 202}

Methods/Properties

BuildQuadraticCandidate(FixedMathSharp.Geometry.ContactQuadratic,System.ReadOnlySpan`1<System.UInt64>,System.ReadOnlySpan`1<System.UInt64>,System.Span`1<System.UInt64>,System.Span`1<System.Int32>)
BuildRadialCandidate(System.ReadOnlySpan`1<System.UInt64>,System.Int32,System.ReadOnlySpan`1<System.UInt64>,System.ReadOnlySpan`1<System.UInt64>,System.Span`1<System.UInt64>,System.Span`1<System.Int32>)
WriteWorldDirection(FixedMathSharp.Geometry.WideRationalBasis3d,System.ReadOnlySpan`1<System.UInt64>,System.ReadOnlySpan`1<System.Int32>,System.Span`1<System.UInt64>,System.Span`1<System.Int32>,System.Int32)
Dot(FixedMathSharp.Geometry.WideAxis3,System.ReadOnlySpan`1<System.UInt64>,System.ReadOnlySpan`1<System.Int32>,System.Span`1<System.UInt64>,System.Int32&)
Dot(FixedMathSharp.Geometry.WideDirection3d&,System.ReadOnlySpan`1<System.UInt64>,System.ReadOnlySpan`1<System.Int32>,System.Span`1<System.UInt64>,System.Int32&)
ProjectPerpendicular(FixedMathSharp.Geometry.WideAxis3,FixedMathSharp.Geometry.WideAxis3,System.Span`1<System.UInt64>,System.Span`1<System.Int32>)
SumSquares(System.ReadOnlySpan`1<System.UInt64>,System.Span`1<System.UInt64>)
ProjectPerpendicular(FixedMathSharp.Geometry.WideDirection3d&,FixedMathSharp.Geometry.WideDirection3d&,System.Span`1<System.UInt64>,System.Span`1<System.Int32>)
WriteDirection(FixedMathSharp.Geometry.WideAxis3,System.Span`1<System.UInt64>,System.Span`1<System.Int32>)
WriteDirection(FixedMathSharp.Geometry.WideDirection3d&,System.Span`1<System.UInt64>,System.Span`1<System.Int32>)
Add(System.ReadOnlySpan`1<System.UInt64>,System.Int32,System.Span`1<System.UInt64>,System.Int32&)
IsZero(System.ReadOnlySpan`1<System.UInt64>)
Slot(System.Span`1<System.UInt64>,System.Int32)
Slot(System.ReadOnlySpan`1<System.UInt64>,System.Int32)
Slot(System.Span`1<System.UInt64>,System.Int32,System.Int32)
Slot(System.ReadOnlySpan`1<System.UInt64>,System.Int32,System.Int32)
Import(FixedMathSharp.Signed320,System.Span`1<System.UInt64>)
Import(FixedMathSharp.Signed576,System.Span`1<System.UInt64>)
Import(FixedMathSharp.Signed832,System.Span`1<System.UInt64>)
DifferenceOfProducts(FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832,FixedMathSharp.Signed832,System.Span`1<System.UInt64>,System.Int32&)
Component(FixedMathSharp.Geometry.WideAxis3&,System.Int32)
Component(FixedMathSharp.Geometry.WideDirection3d&,System.Int32)
Axis(FixedMathSharp.Signed192,FixedMathSharp.Signed192,FixedMathSharp.Signed192)