< Summary

Information
Class: FixedMathSharp.Geometry.FixedPointAnchor
Assembly: FixedMathSharp
File(s): /home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Anchors/FixedPointAnchor.cs
Line coverage
100%
Covered lines: 246
Uncovered lines: 0
Coverable lines: 246
Total lines: 555
Line coverage: 100%
Branch coverage
100%
Covered branches: 74
Total branches: 74
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%
.ctor(...)100%11100%
.ctor(...)100%11100%
FromValidatedFrame(...)100%11100%
.ctor(...)100%44100%
WithLocalTranslation(...)100%11100%
TryGetPoint(...)100%22100%
TryGetOffsetFrom(...)100%11100%
TryGetScaledOffsetFrom(...)100%66100%
TryGetProjectedOffsetFrom(...)100%44100%
ProjectNonNegativeOffsetFrom(...)100%44100%
CompareSquaredDistance(...)100%66100%
TryGetLocalPointIn(...)100%44100%
TryReframe(...)100%1212100%
CompareLocalFeature(...)100%1616100%
GetLocalFeatureHash64()100%11100%
Equals(...)100%1010100%
Equals(...)100%22100%
GetHashCode()100%22100%
op_Equality(...)100%11100%
op_Inequality(...)100%11100%
CompareRaw(...)100%22100%
KeepHash(...)100%11100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// FixedPointAnchor.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/// Represents a 3D point as a local coordinate in one rigid world-space frame.
 14/// </summary>
 15/// <remarks>
 16/// Keeping the frame components separate allows full-domain geometry to retain
 17/// points whose rotated offset or absolute world coordinate is not representable
 18/// as an intermediate <see cref="Fixed64"/> value.
 19/// Relation-produced anchors can also retain an exact sub-lattice feature term
 20/// that is intentionally not exposed as a public wide-arithmetic primitive.
 21/// Consequently, anchors with identical rounded public local components can
 22/// still compare unequal when they identify distinct exact features.
 23/// </remarks>
 24public readonly struct FixedPointAnchor : IEquatable<FixedPointAnchor>
 25{
 26    /// <summary>
 27    /// Initializes a point anchor from a world origin, normalized local-to-world
 28    /// rotation, and local point.
 29    /// </summary>
 30    /// <exception cref="ArgumentException">
 31    /// <paramref name="rotation"/> is not normalized.
 32    /// </exception>
 33    public FixedPointAnchor(
 34        Vector3d origin,
 35        FixedQuaternion rotation,
 36        Vector3d localPoint)
 788037        : this(origin, rotation, localPoint, Vector3d.Zero)
 787938    { }
 39
 40    /// <summary>
 41    /// Initializes a point anchor from a world origin, normalized local-to-world
 42    /// rotation, and two additive local-space feature components.
 43    /// </summary>
 44    /// <exception cref="ArgumentException">
 45    /// <paramref name="rotation"/> is not normalized.
 46    /// </exception>
 47    public FixedPointAnchor(
 48        Vector3d origin,
 49        FixedQuaternion rotation,
 50        Vector3d localPoint,
 51        Vector3d localDisplacement)
 790252        : this(
 790253            origin,
 790254            rotation,
 790255            localPoint,
 790256            localDisplacement,
 790257            Vector3d.Zero,
 790258            default,
 790259            validateRotation: true)
 790160    { }
 61
 62    internal FixedPointAnchor(
 63        Vector3d origin,
 64        FixedQuaternion rotation,
 65        Vector3d localPoint,
 66        Vector3d localDisplacement,
 67        FixedPointAnchorTerm3d exactLocalTerm)
 510268        : this(
 510269            origin,
 510270            rotation,
 510271            localPoint,
 510272            localDisplacement,
 510273            Vector3d.Zero,
 510274            exactLocalTerm,
 510275            validateRotation: true)
 510276    { }
 77
 78    internal static FixedPointAnchor FromValidatedFrame(
 79        Vector3d origin,
 80        FixedQuaternion rotation,
 81        Vector3d localPoint) =>
 52682        new(
 52683            origin,
 52684            rotation,
 52685            localPoint,
 52686            Vector3d.Zero,
 52687            Vector3d.Zero,
 52688            default,
 52689            validateRotation: false);
 90
 91    private FixedPointAnchor(
 92        Vector3d origin,
 93        FixedQuaternion rotation,
 94        Vector3d localPoint,
 95        Vector3d localDisplacement,
 96        Vector3d localTranslation,
 97        FixedPointAnchorTerm3d exactLocalTerm,
 98        bool validateRotation)
 99    {
 13533100        if (validateRotation && !rotation.IsNormalized())
 1101            throw new ArgumentException("The point-anchor rotation must be normalized.", nameof(rotation));
 102
 13532103        Origin = origin;
 13532104        Rotation = rotation;
 13532105        LocalPoint = localPoint;
 13532106        LocalDisplacement = localDisplacement;
 13532107        LocalTranslation = localTranslation;
 13532108        ExactLocalTerm = exactLocalTerm;
 13532109    }
 110
 111    /// <summary>
 112    /// The world-space origin of the rigid frame.
 113    /// </summary>
 114    public Vector3d Origin { get; }
 115
 116    /// <summary>
 117    /// The normalized local-to-world rotation of the rigid frame.
 118    /// </summary>
 119    public FixedQuaternion Rotation { get; }
 120
 121    /// <summary>
 122    /// The point in the rigid frame's local coordinates.
 123    /// </summary>
 124    public Vector3d LocalPoint { get; }
 125
 126    /// <summary>
 127    /// An additional local-space feature displacement that exact operations
 128    /// add to <see cref="LocalPoint"/> without a scalar intermediate.
 129    /// </summary>
 130    public Vector3d LocalDisplacement { get; }
 131
 132    /// <summary>
 133    /// An independent local-space translation applied to the complete anchored
 134    /// point without merging it into either feature component.
 135    /// </summary>
 136    public Vector3d LocalTranslation { get; }
 137
 138    internal FixedPointAnchorTerm3d ExactLocalTerm { get; }
 139
 140    /// <summary>
 141    /// Returns an anchor for the same exact local feature with the specified
 142    /// independent local-space translation.
 143    /// </summary>
 144    public FixedPointAnchor WithLocalTranslation(
 145        Vector3d localTranslation) =>
 3146        new(
 3147            Origin,
 3148            Rotation,
 3149            LocalPoint,
 3150            LocalDisplacement,
 3151            localTranslation,
 3152            ExactLocalTerm,
 3153            validateRotation: true);
 154
 155    /// <summary>
 156    /// Attempts to materialize the absolute world point.
 157    /// </summary>
 158    public bool TryGetPoint(out Vector3d point)
 159    {
 618160        if (!Rotation.IsNormalized())
 161        {
 1162            point = default;
 1163            return false;
 164        }
 165
 617166        return WidePointAnchor3d.TryGetPoint(
 617167            Origin,
 617168            Rotation,
 617169            LocalPoint,
 617170            LocalDisplacement,
 617171            LocalTranslation,
 617172            ExactLocalTerm,
 617173            out point);
 174    }
 175
 176    /// <summary>
 177    /// Attempts to materialize this point's world-space offset from
 178    /// <paramref name="other"/>.
 179    /// </summary>
 180    public bool TryGetOffsetFrom(
 181        in FixedPointAnchor other,
 182        out Vector3d offset) =>
 1154183        TryGetScaledOffsetFrom(other, Fixed64.One, out offset);
 184
 185    /// <summary>
 186    /// Attempts to materialize this point's world-space offset from
 187    /// <paramref name="other"/> after applying <paramref name="scale"/>.
 188    /// </summary>
 189    /// <remarks>
 190    /// The scale is applied to the complete conceptual difference before its
 191    /// final round-half-to-even conversion.
 192    /// </remarks>
 193    public bool TryGetScaledOffsetFrom(
 194        in FixedPointAnchor other,
 195        Fixed64 scale,
 196        out Vector3d offset)
 197    {
 1424198        if (!Rotation.IsNormalized() || !other.Rotation.IsNormalized())
 199        {
 2200            offset = default;
 2201            return false;
 202        }
 1422203        if (scale == Fixed64.Zero)
 204        {
 2205            offset = Vector3d.Zero;
 2206            return true;
 207        }
 208
 1420209        return WidePointAnchor3d.TryGetRelativeOffset(
 1420210            Origin,
 1420211            Rotation,
 1420212            LocalPoint,
 1420213            LocalDisplacement,
 1420214            LocalTranslation,
 1420215            ExactLocalTerm,
 1420216            other.Origin,
 1420217            other.Rotation,
 1420218            other.LocalPoint,
 1420219            other.LocalDisplacement,
 1420220            other.LocalTranslation,
 1420221            other.ExactLocalTerm,
 1420222            scale,
 1420223            out offset);
 224    }
 225
 226    /// <summary>
 227    /// Attempts to project this point minus <paramref name="other"/> onto
 228    /// <paramref name="direction"/> with one final round-half-to-even
 229    /// conversion.
 230    /// </summary>
 231    public bool TryGetProjectedOffsetFrom(
 232        in FixedPointAnchor other,
 233        Vector3d direction,
 234        out Fixed64 projection)
 235    {
 279236        if (!Rotation.IsNormalized() || !other.Rotation.IsNormalized())
 237        {
 2238            projection = default;
 2239            return false;
 240        }
 241
 277242        return WidePointAnchor3d.TryGetProjectedOffset(
 277243            Origin,
 277244            Rotation,
 277245            LocalPoint,
 277246            LocalDisplacement,
 277247            LocalTranslation,
 277248            ExactLocalTerm,
 277249            other.Origin,
 277250            other.Rotation,
 277251            other.LocalPoint,
 277252            other.LocalDisplacement,
 277253            other.LocalTranslation,
 277254            other.ExactLocalTerm,
 277255            direction,
 277256            out projection);
 257    }
 258
 259    /// <summary>
 260    /// Projects this point minus <paramref name="other"/> onto
 261    /// <paramref name="direction"/> and returns zero for nonpositive results,
 262    /// the positive projection floored to Q32.32, or
 263    /// <see cref="Fixed64.MaxValue"/> when only the final result is
 264    /// unrepresentable.
 265    /// </summary>
 266    /// <exception cref="InvalidOperationException">
 267    /// This anchor does not contain a normalized rotation.
 268    /// </exception>
 269    /// <exception cref="ArgumentException">
 270    /// <paramref name="other"/> does not contain a normalized rotation.
 271    /// </exception>
 272    public Fixed64 ProjectNonNegativeOffsetFrom(
 273        in FixedPointAnchor other,
 274        Vector3d direction)
 275    {
 264276        if (!Rotation.IsNormalized())
 277        {
 1278            throw new InvalidOperationException(
 1279                "The point anchor must have a normalized rotation.");
 280        }
 263281        if (!other.Rotation.IsNormalized())
 282        {
 1283            throw new ArgumentException(
 1284                "The other point anchor must have a normalized rotation.",
 1285                nameof(other));
 286        }
 287
 262288        return WidePointAnchor3d.ProjectNonNegativeOffset(
 262289            Origin,
 262290            Rotation,
 262291            LocalPoint,
 262292            LocalDisplacement,
 262293            LocalTranslation,
 262294            ExactLocalTerm,
 262295            other.Origin,
 262296            other.Rotation,
 262297            other.LocalPoint,
 262298            other.LocalDisplacement,
 262299            other.LocalTranslation,
 262300            other.ExactLocalTerm,
 262301            direction);
 302    }
 303
 304    /// <summary>
 305    /// Compares the exact squared distance from this point to two other
 306    /// anchored points.
 307    /// </summary>
 308    /// <returns>
 309    /// A negative value when <paramref name="first"/> is closer, zero when the
 310    /// distances are equal, or a positive value when
 311    /// <paramref name="second"/> is closer.
 312    /// </returns>
 313    public int CompareSquaredDistance(
 314        in FixedPointAnchor first,
 315        in FixedPointAnchor second)
 316    {
 179317        if (!Rotation.IsNormalized())
 318        {
 1319            throw new InvalidOperationException(
 1320                "The reference point anchor must have a normalized rotation.");
 321        }
 178322        if (!first.Rotation.IsNormalized())
 323        {
 1324            throw new ArgumentException(
 1325                "The first point anchor must have a normalized rotation.",
 1326                nameof(first));
 327        }
 177328        if (!second.Rotation.IsNormalized())
 329        {
 1330            throw new ArgumentException(
 1331                "The second point anchor must have a normalized rotation.",
 1332                nameof(second));
 333        }
 334
 176335        return WidePointAnchor3d.CompareSquaredDistances(
 176336            this,
 176337            first,
 176338            second);
 339    }
 340
 341    /// <summary>
 342    /// Attempts to express this point in another rigid frame's local
 343    /// coordinates without first materializing its absolute world position.
 344    /// </summary>
 345    public bool TryGetLocalPointIn(
 346        Vector3d frameOrigin,
 347        FixedQuaternion frameRotation,
 348        out Vector3d localPoint)
 349    {
 4541350        if (!frameRotation.IsNormalized())
 351        {
 1352            localPoint = default;
 1353            return false;
 354        }
 4540355        if (!Rotation.IsNormalized())
 356        {
 1357            localPoint = default;
 1358            return false;
 359        }
 360
 4539361        return WidePointAnchor3d.TryGetLocalPointIn(
 4539362            Origin,
 4539363            Rotation,
 4539364            LocalPoint,
 4539365            LocalDisplacement,
 4539366            LocalTranslation,
 4539367            ExactLocalTerm,
 4539368            frameOrigin,
 4539369            frameRotation,
 4539370            out localPoint);
 371    }
 372
 373    /// <summary>
 374    /// Attempts to express this exact conceptual point in another rigid frame
 375    /// without discarding any sub-lattice feature information.
 376    /// </summary>
 377    /// <remarks>
 378    /// The operation fails when the target frame would require a general
 379    /// rational local coordinate that a compact point anchor cannot retain.
 380    /// </remarks>
 381    public bool TryReframe(
 382        Vector3d frameOrigin,
 383        FixedQuaternion frameRotation,
 384        out FixedPointAnchor anchor)
 385    {
 7386        if (!Rotation.IsNormalized()
 7387            || !frameRotation.IsNormalized())
 388        {
 2389            anchor = default;
 2390            return false;
 391        }
 5392        if (Origin == frameOrigin && Rotation == frameRotation)
 393        {
 1394            anchor = this;
 1395            return true;
 396        }
 4397        if (!TryGetLocalPointIn(
 4398                frameOrigin,
 4399                frameRotation,
 4400                out Vector3d localPoint))
 401        {
 1402            anchor = default;
 1403            return false;
 404        }
 405
 3406        var candidate = new FixedPointAnchor(
 3407            frameOrigin,
 3408            frameRotation,
 3409            localPoint);
 3410        if (!WidePointAnchor3d.RepresentsSamePoint(this, candidate))
 411        {
 1412            anchor = default;
 1413            return false;
 414        }
 415
 2416        anchor = candidate;
 2417        return true;
 418    }
 419
 420    /// <summary>
 421    /// Compares the complete local feature identity of this anchor with
 422    /// <paramref name="other"/> in deterministic component order.
 423    /// </summary>
 424    /// <remarks>
 425    /// Frame origin, rotation, and <see cref="LocalTranslation"/> are
 426    /// intentionally excluded because they move a feature without changing
 427    /// its local identity. Exact sub-lattice centered-axis residuals are
 428    /// included after the public feature components, so distinct features
 429    /// cannot collapse when their rounded local coordinates are equal.
 430    /// </remarks>
 431    public int CompareLocalFeature(in FixedPointAnchor other)
 432    {
 252433        int comparison = CompareRaw(
 252434            LocalPoint.X.m_rawValue,
 252435            other.LocalPoint.X.m_rawValue);
 252436        if (comparison != 0)
 2437            return comparison;
 250438        comparison = CompareRaw(
 250439            LocalPoint.Y.m_rawValue,
 250440            other.LocalPoint.Y.m_rawValue);
 250441        if (comparison != 0)
 2442            return comparison;
 248443        comparison = CompareRaw(
 248444            LocalPoint.Z.m_rawValue,
 248445            other.LocalPoint.Z.m_rawValue);
 248446        if (comparison != 0)
 2447            return comparison;
 246448        comparison = CompareRaw(
 246449            LocalDisplacement.X.m_rawValue,
 246450            other.LocalDisplacement.X.m_rawValue);
 246451        if (comparison != 0)
 2452            return comparison;
 244453        comparison = CompareRaw(
 244454            LocalDisplacement.Y.m_rawValue,
 244455            other.LocalDisplacement.Y.m_rawValue);
 244456        if (comparison != 0)
 2457            return comparison;
 242458        comparison = CompareRaw(
 242459            LocalDisplacement.Z.m_rawValue,
 242460            other.LocalDisplacement.Z.m_rawValue);
 242461        if (comparison != 0)
 2462            return comparison;
 240463        comparison = CompareRaw(
 240464            ExactLocalTerm.X,
 240465            other.ExactLocalTerm.X);
 240466        if (comparison != 0)
 4467            return comparison;
 236468        comparison = CompareRaw(
 236469            ExactLocalTerm.Y,
 236470            other.ExactLocalTerm.Y);
 236471        return comparison != 0
 236472            ? comparison
 236473            : CompareRaw(
 236474                ExactLocalTerm.Z,
 236475                other.ExactLocalTerm.Z);
 476    }
 477
 478    /// <summary>
 479    /// Returns a stable 64-bit hash of the complete local feature identity.
 480    /// </summary>
 481    public ulong GetLocalFeatureHash64()
 482    {
 24483        ulong hash = 14695981039346656037UL;
 24484        KeepHash(ref hash, LocalPoint.X.m_rawValue);
 24485        KeepHash(ref hash, LocalPoint.Y.m_rawValue);
 24486        KeepHash(ref hash, LocalPoint.Z.m_rawValue);
 24487        KeepHash(ref hash, LocalDisplacement.X.m_rawValue);
 24488        KeepHash(ref hash, LocalDisplacement.Y.m_rawValue);
 24489        KeepHash(ref hash, LocalDisplacement.Z.m_rawValue);
 24490        KeepHash(ref hash, ExactLocalTerm.X);
 24491        KeepHash(ref hash, ExactLocalTerm.Y);
 24492        KeepHash(ref hash, ExactLocalTerm.Z);
 24493        return hash;
 494    }
 495
 496    /// <summary>
 497    /// Returns whether both anchors have identical frames, rounded local
 498    /// components, and any retained exact feature identity.
 499    /// </summary>
 500    public bool Equals(FixedPointAnchor other) =>
 432501        Origin.Equals(other.Origin)
 432502        && Rotation.Equals(other.Rotation)
 432503        && LocalPoint.Equals(other.LocalPoint)
 432504        && LocalDisplacement.Equals(other.LocalDisplacement)
 432505        && LocalTranslation.Equals(other.LocalTranslation)
 432506        && ExactLocalTerm.Equals(other.ExactLocalTerm);
 507
 508    /// <summary>
 509    /// Returns a hash code for the complete frame and exact feature identity.
 510    /// </summary>
 511    public override bool Equals(object? obj) =>
 126512        obj is FixedPointAnchor other && Equals(other);
 513
 514    /// <inheritdoc />
 515    public override int GetHashCode()
 516    {
 517        unchecked
 518        {
 5519            int hash = 17;
 5520            hash = (hash * 31) + Origin.GetHashCode();
 5521            hash = (hash * 31) + Rotation.GetHashCode();
 5522            hash = (hash * 31) + LocalPoint.GetHashCode();
 5523            hash = (hash * 31) + LocalDisplacement.GetHashCode();
 5524            hash = (hash * 31) + LocalTranslation.GetHashCode();
 5525            if (!ExactLocalTerm.IsZero)
 2526                hash = (hash * 31) + ExactLocalTerm.GetHashCode();
 5527            return hash;
 528        }
 529    }
 530
 531    /// <summary>
 532    /// Returns whether two point anchors have identical frame components.
 533    /// </summary>
 534    public static bool operator ==(
 535        FixedPointAnchor left,
 536        FixedPointAnchor right) =>
 283537        left.Equals(right);
 538
 539    /// <summary>
 540    /// Returns whether two point anchors have different frame components.
 541    /// </summary>
 542    public static bool operator !=(
 543        FixedPointAnchor left,
 544        FixedPointAnchor right) =>
 1545        !left.Equals(right);
 546
 547    private static int CompareRaw(long left, long right) =>
 2191548        left < right ? -1 : left > right ? 1 : 0;
 549
 550    private static void KeepHash(ref ulong hash, long value)
 551    {
 216552        hash ^= unchecked((ulong)value);
 216553        hash *= 1099511628211UL;
 216554    }
 555}

Methods/Properties

.ctor(FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion,FixedMathSharp.Vector3d)
.ctor(FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
.ctor(FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Geometry.FixedPointAnchorTerm3d)
FromValidatedFrame(FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion,FixedMathSharp.Vector3d)
.ctor(FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Geometry.FixedPointAnchorTerm3d,System.Boolean)
WithLocalTranslation(FixedMathSharp.Vector3d)
TryGetPoint(FixedMathSharp.Vector3d&)
TryGetOffsetFrom(FixedMathSharp.Geometry.FixedPointAnchor&,FixedMathSharp.Vector3d&)
TryGetScaledOffsetFrom(FixedMathSharp.Geometry.FixedPointAnchor&,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d&)
TryGetProjectedOffsetFrom(FixedMathSharp.Geometry.FixedPointAnchor&,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64&)
ProjectNonNegativeOffsetFrom(FixedMathSharp.Geometry.FixedPointAnchor&,FixedMathSharp.Vector3d)
CompareSquaredDistance(FixedMathSharp.Geometry.FixedPointAnchor&,FixedMathSharp.Geometry.FixedPointAnchor&)
TryGetLocalPointIn(FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion,FixedMathSharp.Vector3d&)
TryReframe(FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion,FixedMathSharp.Geometry.FixedPointAnchor&)
CompareLocalFeature(FixedMathSharp.Geometry.FixedPointAnchor&)
GetLocalFeatureHash64()
Equals(FixedMathSharp.Geometry.FixedPointAnchor)
Equals(System.Object)
GetHashCode()
op_Equality(FixedMathSharp.Geometry.FixedPointAnchor,FixedMathSharp.Geometry.FixedPointAnchor)
op_Inequality(FixedMathSharp.Geometry.FixedPointAnchor,FixedMathSharp.Geometry.FixedPointAnchor)
CompareRaw(System.Int64,System.Int64)
KeepHash(System.UInt64&,System.Int64)