< Summary

Information
Class: FixedMathSharp.Geometry.FixedPointAnchorTerm2d
Assembly: FixedMathSharp
File(s): /home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Anchors/FixedPointAnchorTerms.cs
Line coverage
100%
Covered lines: 51
Uncovered lines: 0
Coverable lines: 51
Total lines: 231
Line coverage: 100%
Branch coverage
100%
Covered branches: 4
Total branches: 4
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_IsZero()100%22100%
CreateCenteredAxisSupport(...)100%11100%
CreateRadialSupport(...)100%11100%
GetResidual(...)100%11100%
Equals(...)100%22100%
GetHashCode()100%11100%

File(s)

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Anchors/FixedPointAnchorTerms.cs

#LineLine coverage
 1//=======================================================================
 2// FixedPointAnchorTerms.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>
 13/// Retains the residual between rounded local feature components and their
 14/// exact centered-axis construction over the shared 2*Q32.32 denominator.
 15/// </summary>
 16internal readonly struct FixedPointAnchorTerm3d : IEquatable<FixedPointAnchorTerm3d>
 17{
 18    internal const long MaximumResidualMagnitude = 1L << 33;
 19
 20    internal readonly long X;
 21    internal readonly long Y;
 22    internal readonly long Z;
 23
 24    private FixedPointAnchorTerm3d(
 25        long x,
 26        long y,
 27        long z)
 28    {
 29        X = x;
 30        Y = y;
 31        Z = z;
 32    }
 33
 34    internal bool IsZero => X == 0L && Y == 0L && Z == 0L;
 35
 36    internal static FixedPointAnchorTerm3d CreateCenteredAxisSupport(
 37        Vector3d localAxis,
 38        Fixed64 signedAxisLength,
 39        Vector3d localRadialDirection,
 40        Fixed64 radius,
 41        Vector3d roundedAxialOffset,
 42        Vector3d roundedRadialOffset) =>
 43        new(
 44            GetResidual(
 45                localAxis.X,
 46                signedAxisLength,
 47                localRadialDirection.X,
 48                radius,
 49                roundedAxialOffset.X,
 50                roundedRadialOffset.X),
 51            GetResidual(
 52                localAxis.Y,
 53                signedAxisLength,
 54                localRadialDirection.Y,
 55                radius,
 56                roundedAxialOffset.Y,
 57                roundedRadialOffset.Y),
 58            GetResidual(
 59                localAxis.Z,
 60                signedAxisLength,
 61                localRadialDirection.Z,
 62                radius,
 63                roundedAxialOffset.Z,
 64                roundedRadialOffset.Z));
 65
 66    internal static FixedPointAnchorTerm3d CreateRadialSupport(
 67        Vector3d localRadialDirection,
 68        Fixed64 radius,
 69        Vector3d roundedRadialOffset) =>
 70        CreateCenteredAxisSupport(
 71            Vector3d.Zero,
 72            Fixed64.Zero,
 73            localRadialDirection,
 74            radius,
 75            Vector3d.Zero,
 76            roundedRadialOffset);
 77
 78    internal static FixedPointAnchorTerm3d LiftPlanarXZ(
 79        FixedPointAnchorTerm2d planarTerm) =>
 80        new(planarTerm.X, 0L, planarTerm.Y);
 81
 82    private static long GetResidual(
 83        Fixed64 localAxis,
 84        Fixed64 signedAxisLength,
 85        Fixed64 localRadialDirection,
 86        Fixed64 radius,
 87        Fixed64 roundedAxialOffset,
 88        Fixed64 roundedRadialOffset)
 89    {
 90        Signed320 exact = WideArithmetic.AddSigned320(
 91            WideArithmetic.MultiplySigned192(
 92                Signed192.Raw(localAxis),
 93                Signed192.Raw(signedAxisLength)),
 94            WideArithmetic.AddSigned320(
 95                WideArithmetic.MultiplySigned192(
 96                    Signed192.Raw(localRadialDirection),
 97                    Signed192.Raw(radius)),
 98                WideArithmetic.MultiplySigned192(
 99                    Signed192.Raw(localRadialDirection),
 100                    Signed192.Raw(radius))));
 101        Signed192 rounded = WideArithmetic.AddSigned192(
 102            Signed192.Raw(roundedAxialOffset),
 103            Signed192.Raw(roundedRadialOffset));
 104        Signed320 residual = WideArithmetic.SubtractSigned320(
 105            exact,
 106            WideArithmetic.MultiplySigned192(
 107                rounded,
 108                Denominator));
 109        // Each rounded term is within half of its source denominator. The
 110        // axial full-length/2 residual is therefore at most one Q32 scale
 111        // unit, as is the doubled radial product residual. Their sum is
 112        // bounded inclusively by 2*Q32 (2^33), so the exact numerator fits in
 113        // one signed word even at a pair of round-to-even ties.
 114        return unchecked((long)residual.Word0);
 115    }
 116
 117    internal static Signed192 Denominator =>
 118        Signed192.Signed(Fixed64.Two.m_rawValue);
 119
 120    public bool Equals(FixedPointAnchorTerm3d other) =>
 121        X == other.X && Y == other.Y && Z == other.Z;
 122
 123    public override int GetHashCode()
 124    {
 125        unchecked
 126        {
 127            int hash = 17;
 128            hash = (hash * 31) + X.GetHashCode();
 129            hash = (hash * 31) + Y.GetHashCode();
 130            hash = (hash * 31) + Z.GetHashCode();
 131            return hash;
 132        }
 133    }
 134}
 135
 136/// <summary>
 137/// Two-dimensional counterpart of <see cref="FixedPointAnchorTerm3d"/>.
 138/// </summary>
 139internal readonly struct FixedPointAnchorTerm2d :
 140    IEquatable<FixedPointAnchorTerm2d>
 141{
 142    internal readonly long X;
 143    internal readonly long Y;
 144
 145    private FixedPointAnchorTerm2d(long x, long y)
 146    {
 218147        X = x;
 218148        Y = y;
 218149    }
 150
 220151    internal bool IsZero => X == 0L && Y == 0L;
 152
 153    internal static FixedPointAnchorTerm2d CreateCenteredAxisSupport(
 154        Vector2d localAxis,
 155        Fixed64 signedAxisLength,
 156        Vector2d localRadialDirection,
 157        Fixed64 radius,
 158        Vector2d roundedAxialOffset,
 159        Vector2d roundedRadialOffset) =>
 218160        new(
 218161            GetResidual(
 218162                localAxis.X,
 218163                signedAxisLength,
 218164                localRadialDirection.X,
 218165                radius,
 218166                roundedAxialOffset.X,
 218167                roundedRadialOffset.X),
 218168            GetResidual(
 218169                localAxis.Y,
 218170                signedAxisLength,
 218171                localRadialDirection.Y,
 218172                radius,
 218173                roundedAxialOffset.Y,
 218174                roundedRadialOffset.Y));
 175
 176    internal static FixedPointAnchorTerm2d CreateRadialSupport(
 177        Vector2d localRadialDirection,
 178        Fixed64 radius,
 179        Vector2d roundedRadialOffset) =>
 21180        CreateCenteredAxisSupport(
 21181            Vector2d.Zero,
 21182            Fixed64.Zero,
 21183            localRadialDirection,
 21184            radius,
 21185            Vector2d.Zero,
 21186            roundedRadialOffset);
 187
 188    private static long GetResidual(
 189        Fixed64 localAxis,
 190        Fixed64 signedAxisLength,
 191        Fixed64 localRadialDirection,
 192        Fixed64 radius,
 193        Fixed64 roundedAxialOffset,
 194        Fixed64 roundedRadialOffset)
 195    {
 436196        Signed320 exact = WideArithmetic.AddSigned320(
 436197            WideArithmetic.MultiplySigned192(
 436198                Signed192.Raw(localAxis),
 436199                Signed192.Raw(signedAxisLength)),
 436200            WideArithmetic.AddSigned320(
 436201                WideArithmetic.MultiplySigned192(
 436202                    Signed192.Raw(localRadialDirection),
 436203                    Signed192.Raw(radius)),
 436204                WideArithmetic.MultiplySigned192(
 436205                    Signed192.Raw(localRadialDirection),
 436206                    Signed192.Raw(radius))));
 436207        Signed192 rounded = WideArithmetic.AddSigned192(
 436208            Signed192.Raw(roundedAxialOffset),
 436209            Signed192.Raw(roundedRadialOffset));
 436210        Signed320 residual = WideArithmetic.SubtractSigned320(
 436211            exact,
 436212            WideArithmetic.MultiplySigned192(
 436213                rounded,
 436214                FixedPointAnchorTerm3d.Denominator));
 436215        return unchecked((long)residual.Word0);
 216    }
 217
 218    public bool Equals(FixedPointAnchorTerm2d other) =>
 13219        X == other.X && Y == other.Y;
 220
 221    public override int GetHashCode()
 222    {
 223        unchecked
 224        {
 2225            int hash = 17;
 2226            hash = (hash * 31) + X.GetHashCode();
 2227            hash = (hash * 31) + Y.GetHashCode();
 2228            return hash;
 229        }
 230    }
 231}