< Summary

Line coverage
100%
Covered lines: 603
Uncovered lines: 0
Coverable lines: 603
Total lines: 1143
Line coverage: 100%
Branch coverage
100%
Covered branches: 108
Total branches: 108
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: IsStrictlyConvex(...)100%11100%
File 1: ContainsPoint(...)100%11100%
File 1: ContainsPoint(...)100%11100%
File 1: GetClosestPointOffset(...)100%11100%
File 1: GetClosestPointAnchor(...)100%11100%
File 1: GetSupportOffset(...)100%11100%
File 1: GetSupportAnchor(...)100%11100%
File 1: TryGetAreaAndCentroid(...)100%11100%
File 1: TryGetConvexContacts(...)100%88100%
File 1: TryGetCircleContact(...)100%44100%
File 1: ValidateVertexOffsets(...)100%22100%
File 1: TryGetSegmentFirstIntersectionDistance(...)100%22100%
File 1: TryGetSegmentFirstIntersectionDistance(...)100%44100%
File 1: TryGetSweptCircleFirstDistance(...)100%44100%
File 1: TryGetSweptCircleFirstDistance(...)100%66100%
File 1: TryGetSweptCenteredCapsuleFirstDistance(...)100%88100%
File 1: TryGetSweptCenteredCapsuleFirstDistance(...)100%44100%
File 1: TryGetSweptCenteredCapsuleFirstDistance(...)100%66100%
File 1: TryGetSweptConvexFirstDistance(...)100%11100%
File 1: TryGetSweptConvexFirstDistance(...)100%22100%
File 1: TryGetSweptConvexFirstDistanceCore(...)100%2020100%
File 1: TryGetSweptCenteredCapsuleFirstDistanceCore(...)100%11100%
File 1: TryGetSweptCenteredCapsuleFirstDistanceCore(...)100%1818100%
File 1: ShouldReplaceSweepCandidate(...)100%66100%
File 1: OrientZeroRadiusSweepNormal(...)100%22100%
File 1: ValidateSweep(...)100%44100%
File 1: ValidateCenteredAxis(...)100%44100%
File 2: IntersectsUprightCapsule(...)100%11100%
File 2: IntersectsSweptUprightCapsuleStrict(...)100%11100%
File 2: ValidatePlanarCapsule(...)100%44100%

File(s)

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Primitives/Relations/FixedConvex2dRelations.cs

#LineLine coverage
 1//=======================================================================
 2// FixedConvex2dRelations.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/// Provides exact relations for convex 2D shapes represented by canonical
 14/// origins, scalar rotations, and local vertex offsets.
 15/// </summary>
 16/// <remarks>
 17/// Boundary-ordered offsets may repeat or be collinear. Closed containment and
 18/// contact queries retain their finite convex hull: a segment for collinear
 19/// offsets, or a point when all offsets coincide. At least three offsets are required.
 20/// </remarks>
 21/// <content>Owns exact planar convex contacts, queries and translated shape intersections.</content>
 22public static partial class FixedConvex2dRelations
 23{
 24    /// <summary>
 25    /// Returns whether boundary-ordered vertices form a strictly convex
 26    /// polygon in either winding direction.
 27    /// </summary>
 28    public static bool IsStrictlyConvex(
 29        ReadOnlySpan<Vector2d> convexVertexOffsets)
 30    {
 531        ValidateVertexOffsets(convexVertexOffsets);
 532        return WideConvex2dRelations.IsStrictlyConvex(convexVertexOffsets);
 33    }
 34
 35    /// <summary>
 36    /// Returns whether a world-space point lies inside or on a closed convex
 37    /// polygon represented by an origin and origin-relative vertices.
 38    /// </summary>
 39    public static bool ContainsPoint(
 40        Vector2d point,
 41        Vector2d convexOrigin,
 42        ReadOnlySpan<Vector2d> convexVertexOffsets)
 43    {
 9244        ValidateVertexOffsets(convexVertexOffsets);
 9245        return WideConvex2dRelations.ContainsPoint(
 9246            point,
 9247            convexOrigin,
 9248            Fixed64.Zero,
 9249            convexVertexOffsets);
 50    }
 51
 52    /// <summary>
 53    /// Returns whether a world-space point lies inside or on a rotated closed
 54    /// convex polygon represented by a frame and local vertex offsets.
 55    /// </summary>
 56    public static bool ContainsPoint(
 57        Vector2d point,
 58        Vector2d convexOrigin,
 59        Fixed64 convexRotation,
 60        ReadOnlySpan<Vector2d> convexVertexOffsets)
 61    {
 41162        ValidateVertexOffsets(convexVertexOffsets);
 41163        return WideConvex2dRelations.ContainsPoint(
 41164            point,
 41165            convexOrigin,
 41166            convexRotation,
 41167            convexVertexOffsets);
 68    }
 69
 70    /// <summary>
 71    /// Finds the polygon-relative closest point to a world-space point without
 72    /// materializing polygon vertices.
 73    /// </summary>
 74    public static Vector2d GetClosestPointOffset(
 75        Vector2d point,
 76        Vector2d convexOrigin,
 77        ReadOnlySpan<Vector2d> convexVertexOffsets)
 78    {
 179        ValidateVertexOffsets(convexVertexOffsets);
 180        return WideConvex2dRelations.GetClosestPointOffset(
 181            point,
 182            Vector2d.Zero,
 183            convexOrigin,
 184            convexVertexOffsets);
 85    }
 86
 87    /// <summary>
 88    /// Finds the closest point on a rotated polygon while retaining that point
 89    /// in the polygon's supplied local frame.
 90    /// </summary>
 91    public static FixedPointAnchor2d GetClosestPointAnchor(
 92        Vector2d point,
 93        Vector2d convexOrigin,
 94        Fixed64 convexRotation,
 95        ReadOnlySpan<Vector2d> convexVertexOffsets)
 96    {
 197        ValidateVertexOffsets(convexVertexOffsets);
 198        return new FixedPointAnchor2d(
 199            convexOrigin,
 1100            convexRotation,
 1101            WideConvex2dRelations.GetClosestPointOffset(
 1102                point,
 1103                Vector2d.Zero,
 1104                convexOrigin,
 1105                convexRotation,
 1106                convexVertexOffsets));
 107    }
 108
 109    /// <summary>
 110    /// Returns the first authored polygon-relative vertex with the greatest
 111    /// exact projection along a direction.
 112    /// </summary>
 113    public static Vector2d GetSupportOffset(
 114        ReadOnlySpan<Vector2d> convexVertexOffsets,
 115        Vector2d direction)
 116    {
 2117        ValidateVertexOffsets(convexVertexOffsets);
 2118        return WideConvex2dRelations.GetSupportOffset(
 2119            convexVertexOffsets,
 2120            direction);
 121    }
 122
 123    /// <summary>
 124    /// Returns the first local vertex with the greatest exact world-space
 125    /// projection along a direction.
 126    /// </summary>
 127    public static FixedPointAnchor2d GetSupportAnchor(
 128        Vector2d convexOrigin,
 129        Fixed64 convexRotation,
 130        ReadOnlySpan<Vector2d> convexVertexOffsets,
 131        Vector2d direction)
 132    {
 1133        ValidateVertexOffsets(convexVertexOffsets);
 1134        return new FixedPointAnchor2d(
 1135            convexOrigin,
 1136            convexRotation,
 1137            WideConvex2dRelations.GetSupportOffset(
 1138                convexRotation,
 1139                convexVertexOffsets,
 1140                direction));
 141    }
 142
 143    /// <summary>
 144    /// Attempts to derive the area and centroid of a boundary-ordered convex
 145    /// polygon without narrowing cross products or weighted-coordinate sums.
 146    /// </summary>
 147    /// <remarks>
 148    /// Area is nonnegative and clamps to <see cref="Fixed64.MaxValue"/> when
 149    /// the conceptual value exceeds the scalar domain. The centroid uses one
 150    /// final round-half-to-even conversion per component.
 151    /// </remarks>
 152    /// <returns>
 153    /// <see langword="false"/> only when the polygon has exact zero signed
 154    /// area or its final centroid is outside the scalar domain.
 155    /// </returns>
 156    public static bool TryGetAreaAndCentroid(
 157        ReadOnlySpan<Vector2d> convexVertexOffsets,
 158        out Fixed64 area,
 159        out Vector2d centroid)
 160    {
 133161        ValidateVertexOffsets(convexVertexOffsets);
 133162        return WideConvex2dRelations.TryGetAreaAndCentroid(
 133163            convexVertexOffsets,
 133164            out area,
 133165            out centroid);
 166    }
 167
 168    /// <summary>
 169    /// Attempts to build up to two local-frame contact-anchor pairs between
 170    /// two rotated closed convex polygons.
 171    /// </summary>
 172    public static bool TryGetConvexContacts(
 173        Vector2d firstOrigin,
 174        Fixed64 firstRotation,
 175        ReadOnlySpan<Vector2d> firstVertexOffsets,
 176        Vector2d secondOrigin,
 177        Fixed64 secondRotation,
 178        ReadOnlySpan<Vector2d> secondVertexOffsets,
 179        Span<FixedPointAnchor2d> firstContacts,
 180        Span<FixedPointAnchor2d> secondContacts,
 181        out int contactCount,
 182        out Vector2d normal,
 183        out Fixed64 depth,
 184        out bool depthIsClamped)
 185    {
 189186        ValidateVertexOffsets(firstVertexOffsets);
 189187        ValidateVertexOffsets(secondVertexOffsets);
 189188        if (firstContacts.Length < 2)
 189        {
 1190            throw new ArgumentException(
 1191                "Contact output requires capacity for two anchors.",
 1192                nameof(firstContacts));
 193        }
 188194        if (secondContacts.Length < 2)
 195        {
 1196            throw new ArgumentException(
 1197                "Contact output requires capacity for two anchors.",
 1198                nameof(secondContacts));
 199        }
 200
 187201        Span<Vector2d> firstOffsets = stackalloc Vector2d[2];
 187202        Span<Vector2d> secondOffsets = stackalloc Vector2d[2];
 187203        if (!WideConvex2dRelations.TryGetContactOffsets(
 187204                firstOrigin,
 187205                firstRotation,
 187206                firstVertexOffsets,
 187207                secondOrigin,
 187208                secondRotation,
 187209                secondVertexOffsets,
 187210                firstOffsets,
 187211                secondOffsets,
 187212                out contactCount,
 187213                out normal,
 187214                out depth,
 187215                out depthIsClamped))
 216        {
 22217            return false;
 218        }
 219
 690220        for (int i = 0; i < contactCount; i++)
 221        {
 180222            firstContacts[i] = new FixedPointAnchor2d(
 180223                firstOrigin,
 180224                firstRotation,
 180225                firstOffsets[i]);
 180226            secondContacts[i] = new FixedPointAnchor2d(
 180227                secondOrigin,
 180228                secondRotation,
 180229                secondOffsets[i]);
 230        }
 165231        return true;
 232    }
 233
 234    /// <summary>
 235    /// Attempts to build a contact-anchor pair between a conceptual circle and
 236    /// a rotated closed convex polygon.
 237    /// </summary>
 238    /// <remarks>
 239    /// A circle's rotation does not change its geometry, but it defines the
 240    /// rigid local frame of the returned circle anchor.
 241    /// </remarks>
 242    public static bool TryGetCircleContact(
 243        Vector2d circleCenter,
 244        Fixed64 circleRotation,
 245        Fixed64 circleRadius,
 246        Vector2d convexOrigin,
 247        Fixed64 convexRotation,
 248        ReadOnlySpan<Vector2d> convexVertexOffsets,
 249        out FixedPointAnchor2d circleContact,
 250        out FixedPointAnchor2d convexContact,
 251        out Vector2d normal,
 252        out Fixed64 depth,
 253        out bool depthIsClamped)
 254    {
 210255        if (circleRadius < Fixed64.Zero)
 1256            throw new ArgumentOutOfRangeException(nameof(circleRadius));
 209257        ValidateVertexOffsets(convexVertexOffsets);
 258
 208259        Span<FixedPointAnchor2d> circleContacts =
 208260            stackalloc FixedPointAnchor2d[2];
 208261        Span<FixedPointAnchor2d> convexContacts =
 208262            stackalloc FixedPointAnchor2d[2];
 208263        if (!WideCenteredCapsule2dRelations.TryGetContacts(
 208264                circleCenter,
 208265                circleRotation,
 208266                Vector2d.Right,
 208267                Fixed64.Zero,
 208268                circleRadius,
 208269                convexOrigin,
 208270                convexRotation,
 208271                convexVertexOffsets,
 208272                circleContacts,
 208273                convexContacts,
 208274                out _,
 208275                out normal,
 208276                out depth,
 208277                out depthIsClamped))
 278        {
 113279            circleContact = default;
 113280            convexContact = default;
 113281            return false;
 282        }
 283
 95284        circleContact = circleContacts[0];
 95285        convexContact = convexContacts[0];
 95286        return true;
 287    }
 288
 289    private static void ValidateVertexOffsets(
 290        ReadOnlySpan<Vector2d> convexVertexOffsets)
 291    {
 3898292        if (convexVertexOffsets.Length < 3)
 293        {
 2294            throw new ArgumentException(
 2295                "A convex polygon requires at least three vertex offsets.",
 2296                nameof(convexVertexOffsets));
 297        }
 3896298    }
 299
 300    /// <summary>
 301    /// Finds the first distance where a finite directed segment reaches a
 302    /// closed convex polygon.
 303    /// </summary>
 304    public static bool TryGetSegmentFirstIntersectionDistance(
 305        Vector2d start,
 306        Vector2d direction,
 307        Fixed64 maximumDistance,
 308        Vector2d convexOrigin,
 309        ReadOnlySpan<Vector2d> convexVertexOffsets,
 310        out Fixed64 distance,
 311        out Vector2d normal,
 312        out Vector2d convexContactOffset)
 313    {
 174314        ValidateSweep(direction, maximumDistance);
 174315        ValidateVertexOffsets(convexVertexOffsets);
 174316        if (WideConvex2dRelations.ContainsPoint(
 174317                start,
 174318                convexOrigin,
 174319                Fixed64.Zero,
 174320                convexVertexOffsets))
 321        {
 1322            distance = Fixed64.Zero;
 1323            normal = -direction;
 1324            convexContactOffset =
 1325                WideConvex2dRelations.GetSweptPointTargetContactOffset(
 1326                start,
 1327                Vector2d.Zero,
 1328                Vector2d.Zero,
 1329                convexOrigin,
 1330                convexVertexOffsets,
 1331                normal);
 1332            return true;
 333        }
 334
 173335        return TryGetSweptCenteredCapsuleFirstDistanceCore(
 173336            start,
 173337            Vector2d.Right,
 173338            Fixed64.Zero,
 173339            Fixed64.Zero,
 173340            direction,
 173341            maximumDistance,
 173342            convexOrigin,
 173343            convexVertexOffsets,
 173344            out distance,
 173345            out normal,
 173346            out convexContactOffset);
 347    }
 348
 349    /// <summary>
 350    /// Finds the first distance where a finite directed segment reaches a
 351    /// rotated closed convex polygon.
 352    /// </summary>
 353    public static bool TryGetSegmentFirstIntersectionDistance(
 354        Vector2d start,
 355        Vector2d direction,
 356        Fixed64 maximumDistance,
 357        Vector2d convexOrigin,
 358        Fixed64 convexRotation,
 359        ReadOnlySpan<Vector2d> convexVertexOffsets,
 360        out Fixed64 distance,
 361        out Vector2d normal,
 362        out FixedPointAnchor2d convexContact)
 363    {
 5364        ValidateSweep(direction, maximumDistance);
 5365        ValidateVertexOffsets(convexVertexOffsets);
 366        Vector2d contactOffset;
 5367        if (WideConvex2dRelations.ContainsPoint(
 5368                start,
 5369                convexOrigin,
 5370                convexRotation,
 5371                convexVertexOffsets))
 372        {
 1373            distance = Fixed64.Zero;
 1374            normal = -direction;
 1375            contactOffset =
 1376                WideConvex2dRelations.GetSweptPointTargetContactOffset(
 1377                    start,
 1378                    Vector2d.Zero,
 1379                    Vector2d.Zero,
 1380                    convexOrigin,
 1381                    convexRotation,
 1382                    convexVertexOffsets,
 1383                    normal);
 384        }
 4385        else if (!TryGetSweptCenteredCapsuleFirstDistanceCore(
 4386                     start,
 4387                     Vector2d.Right,
 4388                     Fixed64.Zero,
 4389                     Fixed64.Zero,
 4390                     direction,
 4391                     maximumDistance,
 4392                     convexOrigin,
 4393                     convexRotation,
 4394                     convexVertexOffsets,
 4395                     out distance,
 4396                     out normal,
 4397                     out contactOffset))
 398        {
 1399            convexContact = default;
 1400            return false;
 401        }
 402
 4403        convexContact = new FixedPointAnchor2d(
 4404            convexOrigin,
 4405            convexRotation,
 4406            contactOffset);
 4407        return true;
 408    }
 409
 410    /// <summary>
 411    /// Finds the first distance where a translated conceptual circle reaches a
 412    /// closed convex polygon.
 413    /// </summary>
 414    public static bool TryGetSweptCircleFirstDistance(
 415        Vector2d circleCenter,
 416        Fixed64 circleRadius,
 417        Vector2d direction,
 418        Fixed64 maximumDistance,
 419        Vector2d convexOrigin,
 420        ReadOnlySpan<Vector2d> convexVertexOffsets,
 421        out Fixed64 distance,
 422        out Vector2d normal,
 423        out Vector2d convexContactOffset)
 424    {
 86425        if (circleRadius < Fixed64.Zero)
 1426            throw new ArgumentOutOfRangeException(nameof(circleRadius));
 85427        ValidateSweep(direction, maximumDistance);
 85428        ValidateVertexOffsets(convexVertexOffsets);
 85429        if (TryGetCircleContact(
 85430                circleCenter,
 85431                Fixed64.Zero,
 85432                circleRadius,
 85433                convexOrigin,
 85434                Fixed64.Zero,
 85435                convexVertexOffsets,
 85436                out _,
 85437                out FixedPointAnchor2d initialContact,
 85438                out normal,
 85439                out _,
 85440                out _))
 441        {
 2442            distance = Fixed64.Zero;
 2443            convexContactOffset = initialContact.LocalPoint;
 2444            return true;
 445        }
 446
 83447        return TryGetSweptCenteredCapsuleFirstDistanceCore(
 83448            circleCenter,
 83449            Vector2d.Right,
 83450            Fixed64.Zero,
 83451            circleRadius,
 83452            direction,
 83453            maximumDistance,
 83454            convexOrigin,
 83455            convexVertexOffsets,
 83456            out distance,
 83457            out normal,
 83458            out convexContactOffset);
 459    }
 460
 461    /// <summary>
 462    /// Finds the first distance where a translated conceptual circle reaches
 463    /// a rotated closed convex polygon.
 464    /// </summary>
 465    public static bool TryGetSweptCircleFirstDistance(
 466        Vector2d circleCenter,
 467        Fixed64 circleRadius,
 468        Vector2d direction,
 469        Fixed64 maximumDistance,
 470        Vector2d convexOrigin,
 471        Fixed64 convexRotation,
 472        ReadOnlySpan<Vector2d> convexVertexOffsets,
 473        out Fixed64 distance,
 474        out Vector2d normal,
 475        out FixedPointAnchor2d convexContact)
 476    {
 20477        if (circleRadius < Fixed64.Zero)
 1478            throw new ArgumentOutOfRangeException(nameof(circleRadius));
 19479        ValidateSweep(direction, maximumDistance);
 19480        ValidateVertexOffsets(convexVertexOffsets);
 481        Vector2d contactOffset;
 19482        if (TryGetCircleContact(
 19483                circleCenter,
 19484                Fixed64.Zero,
 19485                circleRadius,
 19486                convexOrigin,
 19487                convexRotation,
 19488                convexVertexOffsets,
 19489                out _,
 19490                out FixedPointAnchor2d initialContact,
 19491                out normal,
 19492                out _,
 19493                out _))
 494        {
 1495            distance = Fixed64.Zero;
 1496            convexContact = initialContact;
 1497            return true;
 498        }
 18499        if (!TryGetSweptCenteredCapsuleFirstDistanceCore(
 18500                circleCenter,
 18501                Vector2d.Right,
 18502                Fixed64.Zero,
 18503                circleRadius,
 18504                direction,
 18505                maximumDistance,
 18506                convexOrigin,
 18507                convexRotation,
 18508                convexVertexOffsets,
 18509                out distance,
 18510                out normal,
 18511                out contactOffset))
 512        {
 1513            convexContact = default;
 1514            return false;
 515        }
 516
 17517        convexContact = new FixedPointAnchor2d(
 17518            convexOrigin,
 17519            convexRotation,
 17520            contactOffset);
 17521        return true;
 522    }
 523
 524    /// <summary>
 525    /// Finds the first distance where a translated centered rotated capsule
 526    /// reaches a rotated closed convex polygon.
 527    /// </summary>
 528    public static bool TryGetSweptCenteredCapsuleFirstDistance(
 529        Vector2d capsuleCenter,
 530        Fixed64 capsuleRotation,
 531        Fixed64 capsuleAxisLength,
 532        Fixed64 capsuleRadius,
 533        Vector2d direction,
 534        Fixed64 maximumDistance,
 535        Vector2d convexOrigin,
 536        Fixed64 convexRotation,
 537        ReadOnlySpan<Vector2d> convexVertexOffsets,
 538        out Fixed64 distance,
 539        out Vector2d normal,
 540        out FixedPointAnchor2d convexContact)
 541    {
 5542        if (capsuleAxisLength < Fixed64.Zero)
 1543            throw new ArgumentOutOfRangeException(nameof(capsuleAxisLength));
 4544        if (capsuleRadius < Fixed64.Zero)
 1545            throw new ArgumentOutOfRangeException(nameof(capsuleRadius));
 3546        ValidateSweep(direction, maximumDistance);
 3547        ValidateVertexOffsets(convexVertexOffsets);
 548
 3549        Span<FixedPointAnchor2d> capsuleContacts =
 3550            stackalloc FixedPointAnchor2d[2];
 3551        Span<FixedPointAnchor2d> convexContacts =
 3552            stackalloc FixedPointAnchor2d[2];
 3553        if (FixedSegment2d.TryGetCenteredCapsuleConvexContacts(
 3554                capsuleCenter,
 3555                capsuleRotation,
 3556                Vector2d.Forward,
 3557                capsuleAxisLength,
 3558                capsuleRadius,
 3559                convexOrigin,
 3560                convexRotation,
 3561                convexVertexOffsets,
 3562                capsuleContacts,
 3563                convexContacts,
 3564                out int contactCount,
 3565                out normal,
 3566                out _,
 3567                out _))
 568        {
 1569            distance = Fixed64.Zero;
 1570            convexContact = convexContacts[contactCount - 1];
 1571            return true;
 572        }
 573
 2574        Vector2d capsuleAxis = new(
 2575            -FixedMath.Sin(capsuleRotation),
 2576            FixedMath.Cos(capsuleRotation));
 2577        if (!TryGetSweptCenteredCapsuleFirstDistanceCore(
 2578                capsuleCenter,
 2579                capsuleAxis,
 2580                capsuleAxisLength,
 2581                capsuleRadius,
 2582                direction,
 2583                maximumDistance,
 2584                convexOrigin,
 2585                convexRotation,
 2586                convexVertexOffsets,
 2587                out distance,
 2588                out normal,
 2589                out Vector2d contactOffset))
 590        {
 1591            convexContact = default;
 1592            return false;
 593        }
 594
 1595        convexContact = new FixedPointAnchor2d(
 1596            convexOrigin,
 1597            convexRotation,
 1598            contactOffset);
 1599        return true;
 600    }
 601
 602    /// <summary>
 603    /// Finds the first distance where a translated conceptual centered
 604    /// capsule reaches a closed convex polygon.
 605    /// </summary>
 606    public static bool TryGetSweptCenteredCapsuleFirstDistance(
 607        Vector2d capsuleCenter,
 608        Vector2d capsuleAxisDirection,
 609        Fixed64 capsuleAxisLength,
 610        Fixed64 capsuleRadius,
 611        Vector2d direction,
 612        Fixed64 maximumDistance,
 613        Vector2d convexOrigin,
 614        ReadOnlySpan<Vector2d> convexVertexOffsets,
 615        out Fixed64 distance,
 616        out Vector2d normal,
 617        out Vector2d convexContactOffset)
 618    {
 122619        ValidateCenteredAxis(
 122620            capsuleAxisDirection,
 122621            capsuleAxisLength);
 120622        if (capsuleRadius < Fixed64.Zero)
 1623            throw new ArgumentOutOfRangeException(nameof(capsuleRadius));
 119624        ValidateSweep(direction, maximumDistance);
 119625        ValidateVertexOffsets(convexVertexOffsets);
 119626        Span<FixedPointAnchor2d> capsuleContacts =
 119627            stackalloc FixedPointAnchor2d[2];
 119628        Span<FixedPointAnchor2d> convexContacts =
 119629            stackalloc FixedPointAnchor2d[2];
 119630        if (WideCenteredCapsule2dRelations.TryGetContacts(
 119631                capsuleCenter,
 119632                Fixed64.Zero,
 119633                capsuleAxisDirection,
 119634                capsuleAxisLength,
 119635                capsuleRadius,
 119636                convexOrigin,
 119637                Fixed64.Zero,
 119638                convexVertexOffsets,
 119639                capsuleContacts,
 119640                convexContacts,
 119641                out int contactCount,
 119642                out normal,
 119643                out _,
 119644                out _))
 645        {
 2646            distance = Fixed64.Zero;
 2647            convexContactOffset =
 2648                convexContacts[contactCount - 1].LocalPoint;
 2649            return true;
 650        }
 651
 117652        return TryGetSweptCenteredCapsuleFirstDistanceCore(
 117653            capsuleCenter,
 117654            capsuleAxisDirection,
 117655            capsuleAxisLength,
 117656            capsuleRadius,
 117657            direction,
 117658            maximumDistance,
 117659            convexOrigin,
 117660            convexVertexOffsets,
 117661            out distance,
 117662            out normal,
 117663            out convexContactOffset);
 664    }
 665
 666    /// <summary>
 667    /// Finds the first distance where a translated conceptual centered capsule
 668    /// reaches a rotated closed convex polygon.
 669    /// </summary>
 670    public static bool TryGetSweptCenteredCapsuleFirstDistance(
 671        Vector2d capsuleCenter,
 672        Vector2d capsuleAxisDirection,
 673        Fixed64 capsuleAxisLength,
 674        Fixed64 capsuleRadius,
 675        Vector2d direction,
 676        Fixed64 maximumDistance,
 677        Vector2d convexOrigin,
 678        Fixed64 convexRotation,
 679        ReadOnlySpan<Vector2d> convexVertexOffsets,
 680        out Fixed64 distance,
 681        out Vector2d normal,
 682        out FixedPointAnchor2d convexContact)
 683    {
 24684        ValidateCenteredAxis(capsuleAxisDirection, capsuleAxisLength);
 24685        if (capsuleRadius < Fixed64.Zero)
 1686            throw new ArgumentOutOfRangeException(nameof(capsuleRadius));
 23687        ValidateSweep(direction, maximumDistance);
 23688        ValidateVertexOffsets(convexVertexOffsets);
 23689        Span<FixedPointAnchor2d> capsuleContacts =
 23690            stackalloc FixedPointAnchor2d[2];
 23691        Span<FixedPointAnchor2d> convexContacts =
 23692            stackalloc FixedPointAnchor2d[2];
 23693        if (WideCenteredCapsule2dRelations.TryGetContacts(
 23694                capsuleCenter,
 23695                Fixed64.Zero,
 23696                capsuleAxisDirection,
 23697                capsuleAxisLength,
 23698                capsuleRadius,
 23699                convexOrigin,
 23700                convexRotation,
 23701                convexVertexOffsets,
 23702                capsuleContacts,
 23703                convexContacts,
 23704                out int contactCount,
 23705                out normal,
 23706                out _,
 23707                out _))
 708        {
 3709            distance = Fixed64.Zero;
 3710            convexContact = convexContacts[contactCount - 1];
 3711            return true;
 712        }
 713
 20714        if (!TryGetSweptCenteredCapsuleFirstDistanceCore(
 20715                capsuleCenter,
 20716                capsuleAxisDirection,
 20717                capsuleAxisLength,
 20718                capsuleRadius,
 20719                direction,
 20720                maximumDistance,
 20721                convexOrigin,
 20722                convexRotation,
 20723                convexVertexOffsets,
 20724                out distance,
 20725                out normal,
 20726                out Vector2d contactOffset))
 727        {
 2728            convexContact = default;
 2729            return false;
 730        }
 731
 18732        convexContact = new FixedPointAnchor2d(
 18733            convexOrigin,
 18734            convexRotation,
 18735            contactOffset);
 18736        return true;
 737    }
 738
 739    /// <summary>
 740    /// Finds the first distance where a translated closed convex polygon
 741    /// reaches another closed convex polygon.
 742    /// </summary>
 743    public static bool TryGetSweptConvexFirstDistance(
 744        Vector2d moverOrigin,
 745        ReadOnlySpan<Vector2d> moverVertexOffsets,
 746        Vector2d direction,
 747        Fixed64 maximumDistance,
 748        Vector2d targetOrigin,
 749        ReadOnlySpan<Vector2d> targetVertexOffsets,
 750        out Fixed64 distance,
 751        out Vector2d normal,
 752        out Vector2d targetContactOffset) =>
 106753        TryGetSweptConvexFirstDistanceCore(
 106754            moverOrigin,
 106755            Fixed64.Zero,
 106756            moverVertexOffsets,
 106757            direction,
 106758            maximumDistance,
 106759            targetOrigin,
 106760            Fixed64.Zero,
 106761            targetVertexOffsets,
 106762            out distance,
 106763            out normal,
 106764            out targetContactOffset);
 765
 766    /// <summary>
 767    /// Finds the first distance where a translated rotated convex polygon
 768    /// reaches another rotated closed convex polygon.
 769    /// </summary>
 770    public static bool TryGetSweptConvexFirstDistance(
 771        Vector2d moverOrigin,
 772        Fixed64 moverRotation,
 773        ReadOnlySpan<Vector2d> moverVertexOffsets,
 774        Vector2d direction,
 775        Fixed64 maximumDistance,
 776        Vector2d targetOrigin,
 777        Fixed64 targetRotation,
 778        ReadOnlySpan<Vector2d> targetVertexOffsets,
 779        out Fixed64 distance,
 780        out Vector2d normal,
 781        out FixedPointAnchor2d targetContact)
 782    {
 25783        if (!TryGetSweptConvexFirstDistanceCore(
 25784                moverOrigin,
 25785                moverRotation,
 25786                moverVertexOffsets,
 25787                direction,
 25788                maximumDistance,
 25789                targetOrigin,
 25790                targetRotation,
 25791                targetVertexOffsets,
 25792                out distance,
 25793                out normal,
 25794                out Vector2d targetContactOffset))
 795        {
 1796            targetContact = default;
 1797            return false;
 798        }
 799
 24800        targetContact = new FixedPointAnchor2d(
 24801            targetOrigin,
 24802            targetRotation,
 24803            targetContactOffset);
 24804        return true;
 805    }
 806
 807    // Authored mode consumes an already admitted displacement and its positive
 808    // representable length; public direction/distance entry points keep validation.
 809    internal static bool TryGetSweptConvexFirstDistanceCore(
 810        Vector2d moverOrigin,
 811        Fixed64 moverRotation,
 812        ReadOnlySpan<Vector2d> moverVertexOffsets,
 813        Vector2d direction,
 814        Fixed64 maximumDistance,
 815        Vector2d targetOrigin,
 816        Fixed64 targetRotation,
 817        ReadOnlySpan<Vector2d> targetVertexOffsets,
 818        out Fixed64 distance,
 819        out Vector2d normal,
 820        out Vector2d targetContactOffset,
 821        bool authoredDisplacement = false)
 822    {
 132823        ValidateVertexOffsets(moverVertexOffsets);
 132824        ValidateVertexOffsets(targetVertexOffsets);
 132825        if (!authoredDisplacement)
 131826            ValidateSweep(direction, maximumDistance);
 130827        Span<Vector2d> moverContacts = stackalloc Vector2d[2];
 130828        Span<Vector2d> targetContacts = stackalloc Vector2d[2];
 130829        if (WideConvex2dRelations.TryGetContactOffsets(
 130830                moverOrigin,
 130831                moverRotation,
 130832                moverVertexOffsets,
 130833                targetOrigin,
 130834                targetRotation,
 130835                targetVertexOffsets,
 130836                moverContacts,
 130837                targetContacts,
 130838                out int contactCount,
 130839                out normal,
 130840                out _,
 130841                out _))
 842        {
 3843            distance = Fixed64.Zero;
 3844            targetContactOffset = targetContacts[contactCount - 1];
 3845            return true;
 846        }
 847
 127848        bool found = false;
 127849        distance = default;
 127850        normal = default;
 127851        targetContactOffset = default;
 127852        for (int moverIndex = 0;
 629853            moverIndex < moverVertexOffsets.Length;
 502854            moverIndex++)
 855        {
 502856            Vector2d moverStart = moverVertexOffsets[moverIndex];
 502857            Vector2d moverEnd = moverVertexOffsets[
 502858                moverIndex + 1 == moverVertexOffsets.Length
 502859                    ? 0
 502860                    : moverIndex + 1];
 502861            for (int targetIndex = 0;
 2092862                targetIndex < targetVertexOffsets.Length;
 1590863                targetIndex++)
 864            {
 1590865                Vector2d targetStart = targetVertexOffsets[targetIndex];
 1590866                Vector2d targetEnd = targetVertexOffsets[
 1590867                    targetIndex + 1 == targetVertexOffsets.Length
 1590868                        ? 0
 1590869                        : targetIndex + 1];
 1590870                if (WideFiniteAxisIntersection
 1590871                    .TryGetSweptOriginOffsetSegmentsFirstDistance(
 1590872                        moverOrigin,
 1590873                        moverRotation,
 1590874                        moverStart,
 1590875                        moverEnd,
 1590876                        Fixed64.Zero,
 1590877                        direction,
 1590878                        maximumDistance,
 1590879                        targetOrigin,
 1590880                        targetRotation,
 1590881                        targetStart,
 1590882                        targetEnd,
 1590883                        Fixed64.Zero,
 1590884                        out Fixed64 candidateDistance,
 1590885                        out _,
 1590886                        authoredDisplacement))
 887                {
 950888                    if (!found || candidateDistance < distance)
 889                    {
 137890                        found = true;
 137891                        distance = candidateDistance;
 892                    }
 893                }
 894            }
 895        }
 896
 127897        if (!found)
 1898            return false;
 899
 126900        WideConvex2dRelations.GetSweptConvexContact(
 126901            moverOrigin, moverRotation, moverVertexOffsets, targetOrigin, targetRotation, targetVertexOffsets,
 126902            direction, out normal, out targetContactOffset);
 126903        return true;
 904    }
 905
 906    private static bool TryGetSweptCenteredCapsuleFirstDistanceCore(
 907        Vector2d center,
 908        Vector2d axisDirection,
 909        Fixed64 axisLength,
 910        Fixed64 radius,
 911        Vector2d direction,
 912        Fixed64 maximumDistance,
 913        Vector2d convexOrigin,
 914        ReadOnlySpan<Vector2d> convexVertexOffsets,
 915        out Fixed64 distance,
 916        out Vector2d normal,
 917        out Vector2d convexContactOffset) =>
 373918        TryGetSweptCenteredCapsuleFirstDistanceCore(
 373919            center,
 373920            axisDirection,
 373921            axisLength,
 373922            radius,
 373923            direction,
 373924            maximumDistance,
 373925            convexOrigin,
 373926            Fixed64.Zero,
 373927            convexVertexOffsets,
 373928            out distance,
 373929            out normal,
 373930            out convexContactOffset);
 931
 932    // Chord mode retains a physical-distance numerator over the admitted length,
 933    // so anchor reconstruction does not quantize time to a second Fixed64 fraction.
 934    internal static bool TryGetSweptCenteredCapsuleFirstDistanceCore(
 935        Vector2d center,
 936        Vector2d axisDirection,
 937        Fixed64 axisLength,
 938        Fixed64 radius,
 939        Vector2d direction,
 940        Fixed64 maximumDistance,
 941        Vector2d convexOrigin,
 942        Fixed64 convexRotation,
 943        ReadOnlySpan<Vector2d> convexVertexOffsets,
 944        out Fixed64 distance,
 945        out Vector2d normal,
 946        out Vector2d convexContactOffset,
 947        bool authoredDisplacement = false)
 948    {
 433949        bool found = false;
 433950        distance = default;
 433951        normal = default;
 433952        convexContactOffset = default;
 3750953        for (int i = 0; i < convexVertexOffsets.Length; i++)
 954        {
 1442955            Vector2d start = convexVertexOffsets[i];
 1442956            Vector2d end = convexVertexOffsets[
 1442957                i + 1 == convexVertexOffsets.Length ? 0 : i + 1];
 1442958            if (WideFiniteAxisIntersection
 1442959                .TryGetSweptCenteredCapsuleOriginOffsetSegmentFirstDistance(
 1442960                    center,
 1442961                    axisDirection,
 1442962                    axisLength,
 1442963                    radius,
 1442964                    direction,
 1442965                    maximumDistance,
 1442966                    convexOrigin,
 1442967                    convexRotation,
 1442968                    start,
 1442969                    end,
 1442970                    Fixed64.Zero,
 1442971                    out Fixed64 candidateDistance,
 1442972                    out Vector2d candidateNormal,
 1442973                    authoredDisplacement))
 974            {
 975                // Positive radius preserves the geometric side; a rounded tangent normal's motion dot need not be zero.
 1045976                candidateNormal = radius == Fixed64.Zero
 1045977                    ? OrientZeroRadiusSweepNormal(candidateNormal, direction)
 1045978                    : -candidateNormal;
 1045979                if (!ShouldReplaceSweepCandidate(
 1045980                        candidateDistance,
 1045981                        candidateNormal,
 1045982                        direction,
 1045983                        found,
 1045984                        distance,
 1045985                        normal))
 986                {
 987                    continue;
 988                }
 449989                found = true;
 449990                distance = candidateDistance;
 449991                normal = candidateNormal;
 992            }
 993        }
 994
 433995        if (!found)
 5996            return false;
 997
 428998        if (radius == Fixed64.Zero && WideConvex2dRelations.TryGetSweptCenteredAxisContact(
 428999                center, axisDirection, axisLength, convexOrigin, convexRotation, convexVertexOffsets,
 4281000                direction, out Vector2d entryNormal, out convexContactOffset))
 1001        {
 2841002            normal = entryNormal;
 2841003            return true;
 1004        }
 1441005        Vector2d translation = authoredDisplacement
 1441006            ? new FixedSegment2d(Vector2d.Zero, direction).GetPointAtDistance(distance, maximumDistance)
 1441007            : direction * distance;
 1441008        FixedPointAnchor2d sourceSupport =
 1441009            WideFiniteAxisIntersection.GetCenteredCapsuleSupportAnchor(
 1441010                center,
 1441011                Fixed64.Zero,
 1441012                axisDirection,
 1441013                axisLength,
 1441014                radius,
 1441015                -normal);
 1441016        convexContactOffset =
 1441017            WideConvex2dRelations.GetSweptAnchorTargetContactOffset(
 1441018            sourceSupport,
 1441019            translation,
 1441020            convexOrigin,
 1441021            convexRotation,
 1441022            convexVertexOffsets,
 1441023            normal);
 1441024        return true;
 1025    }
 1026
 1027    private static bool ShouldReplaceSweepCandidate(
 1028        Fixed64 candidateDistance,
 1029        Vector2d candidateNormal,
 1030        Vector2d direction,
 1031        bool found,
 1032        Fixed64 bestDistance,
 1033        Vector2d bestNormal) =>
 10451034        !found
 10451035        || candidateDistance < bestDistance
 10451036        || (candidateDistance == bestDistance
 10451037            && Vector2d.Dot(candidateNormal, direction)
 10451038                < Vector2d.Dot(bestNormal, direction));
 1039
 1040    // A zero-radius crossing can round beyond the face, so its reconstructed normal needs motion orientation.
 1041    private static Vector2d OrientZeroRadiusSweepNormal(Vector2d normal, Vector2d direction) =>
 7191042        Vector2d.Dot(normal, direction) > Fixed64.Zero ? -normal : normal;
 1043
 1044    private static void ValidateSweep(
 1045        Vector2d direction,
 1046        Fixed64 maximumDistance)
 1047    {
 5591048        if (!direction.IsNormalized())
 11049            throw new ArgumentException(
 11050                "Sweep direction must be normalized.",
 11051                nameof(direction));
 5581052        if (maximumDistance < Fixed64.Zero)
 1053        {
 11054            throw new ArgumentOutOfRangeException(
 11055                nameof(maximumDistance));
 1056        }
 5571057    }
 1058
 1059    private static void ValidateCenteredAxis(
 1060        Vector2d axisDirection,
 1061        Fixed64 axisLength)
 1062    {
 1461063        if (!axisDirection.IsNormalized())
 1064        {
 11065            throw new ArgumentException(
 11066                "Axis direction must be normalized.",
 11067                nameof(axisDirection));
 1068        }
 1451069        if (axisLength < Fixed64.Zero)
 11070            throw new ArgumentOutOfRangeException(nameof(axisLength));
 1441071    }
 1072}

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Primitives/Relations/FixedConvex2dRelations.PlanarSweep.cs

#LineLine coverage
 1//=======================================================================
 2// FixedConvex2dRelations.PlanarSweep.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>Strict continuous planar capsule coverage.</content>
 13public static partial class FixedConvex2dRelations
 14{
 15    /// <summary>
 16    /// Tests exact closed contact of an upright capsule with a convex polygon,
 17    /// including tangency and zero-radius axis contact.
 18    /// </summary>
 19    /// <remarks>
 20    /// Uses the same shape and polygon preconditions as
 21    /// <see cref="IntersectsSweptUprightCapsuleStrict"/>, but tests one stationary
 22    /// pose and includes the boundary. No rounded contact normal or penetration
 23    /// depth participates in the classification.
 24    /// </remarks>
 25    /// <exception cref="ArgumentException">Fewer than three polygon vertices were supplied.</exception>
 26    /// <exception cref="ArgumentOutOfRangeException">Axis length or radius is negative.</exception>
 27    public static bool IntersectsUprightCapsule(
 28        Vector2d center, Fixed64 axisLength, Fixed64 radius,
 29        Vector2d convexOrigin, ReadOnlySpan<Vector2d> convexVertexOffsets)
 30    {
 9131        ValidatePlanarCapsule(axisLength, radius, convexVertexOffsets);
 9132        return WideConvex2dRelations.IntersectsSweptUprightCapsule(
 9133            center, center, axisLength, radius, convexOrigin, convexVertexOffsets, strict: false);
 34    }
 35
 36    /// <summary>
 37    /// Tests whether an upright capsule swept continuously between two centers
 38    /// overlaps a convex polygon's interior, excluding boundary-only contact.
 39    /// </summary>
 40    /// <remarks>
 41    /// The capsule axis is parallel to <see cref="Vector2d.Forward"/>. Its total
 42    /// height is axis length plus twice radius; zero axis length is a circle.
 43    /// Zero radius tests entry of the swept axis into the polygon interior.
 44    /// Conceptual half-axis endpoints, polygon vertices and the entire chord
 45    /// are evaluated without scalar saturation or rounding, including odd-raw
 46    /// axis lengths. Vertices must be boundary-ordered and convex in either
 47    /// winding; repeated/collinear edges are allowed. An entirely collinear
 48    /// polygon has no interior. Convexity is an authoring precondition, not
 49    /// checked by this query. Work is linear in the vertex count, without allocation.
 50    /// </remarks>
 51    /// <exception cref="ArgumentException">Fewer than three polygon vertices were supplied.</exception>
 52    /// <exception cref="ArgumentOutOfRangeException">Axis length or radius is negative.</exception>
 53    public static bool IntersectsSweptUprightCapsuleStrict(
 54        Vector2d startCenter, Vector2d endCenter, Fixed64 axisLength, Fixed64 radius,
 55        Vector2d convexOrigin, ReadOnlySpan<Vector2d> convexVertexOffsets)
 56    {
 188257        ValidatePlanarCapsule(axisLength, radius, convexVertexOffsets);
 187958        return WideConvex2dRelations.IntersectsSweptUprightCapsule(
 187959            startCenter, endCenter, axisLength, radius, convexOrigin, convexVertexOffsets, strict: true);
 60    }
 61
 62    private static void ValidatePlanarCapsule(
 63        Fixed64 axisLength, Fixed64 radius, ReadOnlySpan<Vector2d> convexVertexOffsets)
 64    {
 197365        ValidateVertexOffsets(convexVertexOffsets);
 197266        if (axisLength < Fixed64.Zero)
 167            throw new ArgumentOutOfRangeException(nameof(axisLength));
 197168        if (radius < Fixed64.Zero)
 169            throw new ArgumentOutOfRangeException(nameof(radius));
 197070    }
 71}

Methods/Properties

IsStrictlyConvex(System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
ContainsPoint(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
ContainsPoint(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
GetClosestPointOffset(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
GetClosestPointAnchor(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
GetSupportOffset(System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Vector2d)
GetSupportAnchor(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Vector2d)
TryGetAreaAndCentroid(System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&)
TryGetConvexContacts(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,System.Span`1<FixedMathSharp.Geometry.FixedPointAnchor2d>,System.Span`1<FixedMathSharp.Geometry.FixedPointAnchor2d>,System.Int32&,FixedMathSharp.Vector2d&,FixedMathSharp.Fixed64&,System.Boolean&)
TryGetCircleContact(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Geometry.FixedPointAnchor2d&,FixedMathSharp.Geometry.FixedPointAnchor2d&,FixedMathSharp.Vector2d&,FixedMathSharp.Fixed64&,System.Boolean&)
ValidateVertexOffsets(System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
TryGetSegmentFirstIntersectionDistance(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Vector2d&)
TryGetSegmentFirstIntersectionDistance(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Geometry.FixedPointAnchor2d&)
TryGetSweptCircleFirstDistance(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Vector2d&)
TryGetSweptCircleFirstDistance(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Geometry.FixedPointAnchor2d&)
TryGetSweptCenteredCapsuleFirstDistance(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Geometry.FixedPointAnchor2d&)
TryGetSweptCenteredCapsuleFirstDistance(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Vector2d&)
TryGetSweptCenteredCapsuleFirstDistance(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Geometry.FixedPointAnchor2d&)
TryGetSweptConvexFirstDistance(FixedMathSharp.Vector2d,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Vector2d&)
TryGetSweptConvexFirstDistance(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Geometry.FixedPointAnchor2d&)
TryGetSweptConvexFirstDistanceCore(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Vector2d&,System.Boolean)
TryGetSweptCenteredCapsuleFirstDistanceCore(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Vector2d&)
TryGetSweptCenteredCapsuleFirstDistanceCore(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,FixedMathSharp.Fixed64&,FixedMathSharp.Vector2d&,FixedMathSharp.Vector2d&,System.Boolean)
ShouldReplaceSweepCandidate(FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,System.Boolean,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d)
OrientZeroRadiusSweepNormal(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
ValidateSweep(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
ValidateCenteredAxis(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
IntersectsUprightCapsule(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
IntersectsSweptUprightCapsuleStrict(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
ValidatePlanarCapsule(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)