< Summary

Line coverage
100%
Covered lines: 182
Uncovered lines: 0
Coverable lines: 182
Total lines: 684
Line coverage: 100%
Branch coverage
100%
Covered branches: 66
Total branches: 66
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: .ctor(...)100%11100%
File 2: .ctor(...)100%11100%
File 2: get_Center()100%11100%
File 2: set_Center(...)100%22100%
File 2: get_Size()100%11100%
File 2: set_Size(...)100%11100%
File 2: get_Scope()100%11100%
File 2: get_State()100%11100%
File 2: set_State(...)100%11100%
File 2: FromMinMax(...)100%11100%
File 2: FromCenterAndSize(...)100%11100%
File 2: FromCenterAndScope(...)100%11100%
File 2: FromCenterAndSizeClippedToDomain(...)100%11100%
File 2: FromCenterAndScopeClippedToDomain(...)100%11100%
File 2: FromCenterAndOffsetsClippedToDomain(...)100%44100%
File 2: FromRotatedOffsetsClippedToDomain(...)100%22100%
File 2: SetMinMax(...)100%11100%
File 2: Contains(...)100%66100%
File 2: Contains(...)100%1010100%
File 2: Contains(...)100%66100%
File 2: Intersects(...)100%66100%
File 2: Intersects(...)100%11100%
File 2: IntersectsStrict(...)100%1010100%
File 2: IntersectsStrict(...)100%11100%
File 2: ClampPoint(...)100%11100%
File 2: ProjectPoint(...)100%11100%
File 2: Deconstruct(...)100%11100%
File 2: Equals(...)100%22100%
File 2: Equals(...)100%22100%
File 2: GetHashCode()100%11100%
File 2: op_Equality(...)100%11100%
File 2: op_Inequality(...)100%11100%
File 2: Union(...)100%11100%
File 2: HasPositiveArea()100%22100%
File 2: ComponentMin(...)100%11100%
File 2: ComponentMax(...)100%11100%
File 2: SetCenterAndHalfSize(...)100%44100%
File 2: SetCenterAndHalfSizeClippedToDomain(...)100%11100%
File 2: GetHalfSize(...)100%11100%
File 2: GetScopeMagnitude(...)100%11100%
File 2: CreateUnrepresentableBoundsException()100%11100%
File 2: FromCenteredRotatedCapsuleClippedToDomain(...)100%44100%
File 2: FromCenteredCapsuleClippedToDomain(...)100%66100%

File(s)

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Bounds/FixedBoundArea.BoundingAreaState.cs

#LineLine coverage
 1//=======================================================================
 2// FixedBoundArea.BoundingAreaState.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;
 9using System.Runtime.CompilerServices;
 10using System.Text.Json.Serialization;
 11using MemoryPack;
 12
 13namespace FixedMathSharp.Geometry;
 14
 15/// <content>BoundingAreaState declaration for FixedBoundArea.</content>
 16public partial struct FixedBoundArea
 17{
 18    /// <summary>
 19    /// Represents the normalized serializable state of a two-dimensional axis-aligned bounding area.
 20    /// </summary>
 21    [Serializable]
 22    [MemoryPackable]
 23    public readonly partial struct BoundingAreaState
 24    {
 25        /// <inheritdoc cref="FixedBoundArea.Min"/>
 26        [JsonInclude]
 27        [MemoryPackInclude]
 28        public readonly Vector2d Min;
 29
 30        /// <inheritdoc cref="FixedBoundArea.Max"/>
 31        [JsonInclude]
 32        [MemoryPackInclude]
 33        public readonly Vector2d Max;
 34
 35        /// <summary>
 36        /// Initializes a normalized state from minimum and maximum corners.
 37        /// </summary>
 38        [JsonConstructor]
 39        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 40        public BoundingAreaState(Vector2d min, Vector2d max)
 41        {
 542            Min = ComponentMin(min, max);
 543            Max = ComponentMax(min, max);
 544        }
 45    }
 46}

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Geometry/Bounds/FixedBoundArea.cs

#LineLine coverage
 1//=======================================================================
 2// FixedBoundArea.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;
 9using System.Runtime.CompilerServices;
 10using System.Text.Json.Serialization;
 11using MemoryPack;
 12
 13namespace FixedMathSharp.Geometry;
 14
 15/// <summary>
 16/// Represents a normalized two-dimensional axis-aligned bounding area.
 17/// </summary>
 18/// <remarks>
 19/// FixedMathSharp 2D geometry is plain <see cref="Vector2d"/> plane math. Use
 20/// <see cref="FromMinMax"/>, <see cref="FromCenterAndSize"/>, or
 21/// <see cref="FromCenterAndScope"/> so construction intent is explicit.
 22/// </remarks>
 23[Serializable]
 24[MemoryPackable]
 25public partial struct FixedBoundArea : IEquatable<FixedBoundArea>
 26{
 27
 28    #region Constructors
 29
 30    /// <summary>
 31    /// Initializes a new instance from serialized or caller-provided state.
 32    /// </summary>
 33    [JsonConstructor]
 34    public FixedBoundArea(BoundingAreaState state)
 35    {
 336        State = state;
 337    }
 38
 39    #endregion
 40
 41    #region Properties
 42
 43    /// <summary>
 44    /// The minimum corner of the area.
 45    /// </summary>
 46    [JsonIgnore]
 47    [MemoryPackIgnore]
 48    public Vector2d Min { get; private set; }
 49
 50    /// <summary>
 51    /// The maximum corner of the area.
 52    /// </summary>
 53    [JsonIgnore]
 54    [MemoryPackIgnore]
 55    public Vector2d Max { get; private set; }
 56
 57    /// <summary>
 58    /// The center of the area, rounded to the nearest-even Q32.32 lattice point.
 59    /// </summary>
 60    /// <remarks>
 61    /// Assigning a different center preserves a conservative half-extent. An
 62    /// odd raw-unit span can therefore expand by one raw unit so the assigned
 63    /// center remains exact and the previous area is not under-represented.
 64    /// </remarks>
 65    /// <exception cref="OverflowException">
 66    /// An assigned center would place an endpoint outside the scalar domain.
 67    /// </exception>
 68    [JsonIgnore]
 69    [MemoryPackIgnore]
 70    public Vector2d Center
 71    {
 72        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1673        get => new(
 1674            FixedMath.Midpoint(Min.X, Max.X),
 1675            FixedMath.Midpoint(Min.Y, Max.Y));
 76
 77        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 78        set
 79        {
 480            if (value != Center)
 381                SetCenterAndHalfSize(value, Scope);
 382        }
 83    }
 84
 85    /// <summary>
 86    /// The exact total width and height of the area.
 87    /// </summary>
 88    /// <remarks>
 89    /// Assigned values are normalized by absolute component value and divided
 90    /// outward. An odd raw-unit size therefore expands by one raw unit. Reading
 91    /// this property throws rather than returning a saturated value when an
 92    /// exact component span is not representable by <see cref="Fixed64"/>.
 93    /// </remarks>
 94    /// <exception cref="OverflowException">
 95    /// A component span is not representable, or an assigned size would place
 96    /// an endpoint outside the scalar domain.
 97    /// </exception>
 98    [JsonIgnore]
 99    [MemoryPackIgnore]
 100    public Vector2d Size
 101    {
 102        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 11103        get => new(
 11104            WideGeometry.GetIntervalSize(Min.X, Max.X),
 11105            WideGeometry.GetIntervalSize(Min.Y, Max.Y));
 106
 107        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 108        set
 109        {
 2110            SetCenterAndHalfSize(Center, GetHalfSize(value));
 1111        }
 112    }
 113
 114    /// <summary>
 115    /// The smallest representable half-extent that conservatively contains the
 116    /// area around <see cref="Center"/>.
 117    /// </summary>
 118    /// <exception cref="OverflowException">
 119    /// A conservative half-extent is outside the representable scalar domain.
 120    /// </exception>
 121    [JsonIgnore]
 122    [MemoryPackIgnore]
 123    public Vector2d Scope
 124    {
 125        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 10126        get => new(
 10127            WideGeometry.GetIntervalScope(Min.X, Max.X),
 10128            WideGeometry.GetIntervalScope(Min.Y, Max.Y));
 129    }
 130
 131    /// <summary>
 132    /// Gets or sets the current normalized state of the area.
 133    /// </summary>
 134    [JsonInclude]
 135    [MemoryPackInclude]
 136    public BoundingAreaState State
 137    {
 2138        get => new(Min, Max);
 139
 140        internal set
 141        {
 3142            SetMinMax(value.Min, value.Max);
 3143        }
 144    }
 145
 146    #endregion
 147
 148    #region Factories
 149
 150    /// <summary>
 151    /// Creates a normalized area from minimum and maximum corners.
 152    /// </summary>
 153    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 154    public static FixedBoundArea FromMinMax(Vector2d min, Vector2d max)
 155    {
 350156        var area = default(FixedBoundArea);
 350157        area.SetMinMax(min, max);
 350158        return area;
 159    }
 160
 161    /// <summary>
 162    /// Creates an area from a center point and total size.
 163    /// </summary>
 164    /// <remarks>
 165    /// Negative size components are normalized by absolute value. Odd raw-unit
 166    /// sizes are divided outward and therefore expand by one raw unit.
 167    /// </remarks>
 168    /// <exception cref="OverflowException">
 169    /// The centered area would place an endpoint outside the scalar domain.
 170    /// </exception>
 171    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 172    public static FixedBoundArea FromCenterAndSize(Vector2d center, Vector2d size)
 173    {
 15174        var area = default(FixedBoundArea);
 15175        area.SetCenterAndHalfSize(center, GetHalfSize(size));
 13176        return area;
 177    }
 178
 179    /// <summary>
 180    /// Creates an area from a center point and half-size scope.
 181    /// </summary>
 182    /// <remarks>
 183    /// Negative scope components are normalized by absolute value.
 184    /// </remarks>
 185    /// <exception cref="OverflowException">
 186    /// A scope magnitude is not representable, or the centered area would
 187    /// place an endpoint outside the scalar domain.
 188    /// </exception>
 189    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 190    public static FixedBoundArea FromCenterAndScope(Vector2d center, Vector2d scope)
 191    {
 2192        var area = default(FixedBoundArea);
 2193        area.SetCenterAndHalfSize(center, GetScopeMagnitude(scope));
 1194        return area;
 195    }
 196
 197    /// <summary>
 198    /// Creates the representable-domain intersection of an area described by a
 199    /// center point and total size.
 200    /// </summary>
 201    /// <remarks>
 202    /// Negative size components are normalized by absolute value and odd raw-
 203    /// unit sizes divide outward. Endpoints outside the scalar domain are
 204    /// explicitly clipped to <see cref="Fixed64.MinValue"/> or
 205    /// <see cref="Fixed64.MaxValue"/>.
 206    /// </remarks>
 207    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 208    public static FixedBoundArea FromCenterAndSizeClippedToDomain(Vector2d center, Vector2d size)
 209    {
 1210        var area = default(FixedBoundArea);
 1211        area.SetCenterAndHalfSizeClippedToDomain(center, GetHalfSize(size));
 1212        return area;
 213    }
 214
 215    /// <summary>
 216    /// Creates the representable-domain intersection of an area described by a
 217    /// center point and half-size scope.
 218    /// </summary>
 219    /// <remarks>
 220    /// Negative scope components are normalized by absolute value. Endpoints
 221    /// outside the scalar domain are explicitly clipped to
 222    /// <see cref="Fixed64.MinValue"/> or <see cref="Fixed64.MaxValue"/>.
 223    /// </remarks>
 224    /// <exception cref="OverflowException">
 225    /// A scope magnitude is not representable.
 226    /// </exception>
 227    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 228    public static FixedBoundArea FromCenterAndScopeClippedToDomain(Vector2d center, Vector2d scope)
 229    {
 5230        var area = default(FixedBoundArea);
 5231        area.SetCenterAndHalfSizeClippedToDomain(center, GetScopeMagnitude(scope));
 5232        return area;
 233    }
 234
 235    /// <summary>
 236    /// Creates the representable-domain intersection of bounds described by a
 237    /// center and normalized center-relative minimum and maximum offsets.
 238    /// </summary>
 239    /// <remarks>
 240    /// Each endpoint is formed by one final saturating add, which is the
 241    /// explicit clipping operation. Asymmetric offsets are preserved.
 242    /// </remarks>
 243    /// <exception cref="ArgumentException">
 244    /// A minimum offset component exceeds the matching maximum component.
 245    /// </exception>
 246    public static FixedBoundArea FromCenterAndOffsetsClippedToDomain(
 247        Vector2d center,
 248        Vector2d minimumOffset,
 249        Vector2d maximumOffset)
 250    {
 3251        if (minimumOffset.X > maximumOffset.X
 3252            || minimumOffset.Y > maximumOffset.Y)
 253        {
 2254            throw new ArgumentException(
 2255                "Minimum offsets must not exceed maximum offsets.",
 2256                nameof(minimumOffset));
 257        }
 258
 1259        return FromMinMax(
 1260            center + minimumOffset,
 1261            center + maximumOffset);
 262    }
 263
 264    /// <summary>
 265    /// Creates the representable-domain intersection of bounds around rotated
 266    /// local offsets without materializing any transformed point.
 267    /// </summary>
 268    public static FixedBoundArea FromRotatedOffsetsClippedToDomain(
 269        Vector2d origin,
 270        Fixed64 rotation,
 271        ReadOnlySpan<Vector2d> localOffsets)
 272    {
 3273        if (localOffsets.IsEmpty)
 274        {
 1275            throw new ArgumentException(
 1276                "At least one local offset is required.",
 1277                nameof(localOffsets));
 278        }
 279
 2280        return WideConvex2dRelations.GetBoundsClippedToDomain(
 2281            origin,
 2282            rotation,
 2283            localOffsets);
 284    }
 285
 286    #endregion
 287
 288    #region Mutators
 289
 290    /// <summary>
 291    /// Sets the normalized bounds of the area by specifying minimum and maximum points.
 292    /// </summary>
 293    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 294    public void SetMinMax(Vector2d min, Vector2d max)
 295    {
 354296        Min = ComponentMin(min, max);
 354297        Max = ComponentMax(min, max);
 354298    }
 299
 300    #endregion
 301
 302    #region Spatial Queries
 303
 304    /// <summary>
 305    /// Determines whether the point is inside this area, including the boundary.
 306    /// </summary>
 307    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 308    public bool Contains(Vector2d point)
 309    {
 5310        return point.X >= Min.X && point.X <= Max.X
 5311            && point.Y >= Min.Y && point.Y <= Max.Y;
 312    }
 313
 314    /// <summary>
 315    /// Classifies another area against this area using boundary-inclusive overlap.
 316    /// </summary>
 317    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 318    public FixedEnclosureType Contains(FixedBoundArea area)
 319    {
 3320        if (area.Min.X >= Min.X && area.Max.X <= Max.X
 3321            && area.Min.Y >= Min.Y && area.Max.Y <= Max.Y)
 1322            return FixedEnclosureType.Contains;
 323
 2324        return Intersects(area)
 2325            ? FixedEnclosureType.Intersects
 2326            : FixedEnclosureType.Disjoint;
 327    }
 328
 329    /// <summary>
 330    /// Classifies a circle against this area using boundary-inclusive overlap.
 331    /// </summary>
 332    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 333    public FixedEnclosureType Contains(FixedBoundCircle circle)
 334    {
 9335        if (WideGeometry.ContainsCenteredExtent(Min.X, Max.X, circle.Center.X, circle.Radius)
 9336            && WideGeometry.ContainsCenteredExtent(Min.Y, Max.Y, circle.Center.Y, circle.Radius))
 1337            return FixedEnclosureType.Contains;
 338
 8339        return Intersects(circle)
 8340            ? FixedEnclosureType.Intersects
 8341            : FixedEnclosureType.Disjoint;
 342    }
 343
 344    /// <summary>
 345    /// Determines whether this area overlaps another area, including boundary-only contact.
 346    /// </summary>
 347    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 348    public bool Intersects(FixedBoundArea area)
 349    {
 6350        return Min.X <= area.Max.X && Max.X >= area.Min.X
 6351            && Min.Y <= area.Max.Y && Max.Y >= area.Min.Y;
 352    }
 353
 354    /// <summary>
 355    /// Determines whether this area overlaps a circle, including boundary-only contact.
 356    /// </summary>
 357    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 12358    public bool Intersects(FixedBoundCircle circle) => circle.Intersects(this);
 359
 360    /// <summary>
 361    /// Determines whether this area overlaps another area with positive area on both axes.
 362    /// </summary>
 363    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 364    public bool IntersectsStrict(FixedBoundArea area)
 365    {
 4366        return HasPositiveArea() && area.HasPositiveArea()
 4367            && Min.X < area.Max.X && Max.X > area.Min.X
 4368            && Min.Y < area.Max.Y && Max.Y > area.Min.Y;
 369    }
 370
 371    /// <summary>
 372    /// Determines whether this area overlaps a circle with positive area.
 373    /// </summary>
 374    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 4375    public bool IntersectsStrict(FixedBoundCircle circle) => circle.IntersectsStrict(this);
 376
 377    /// <summary>
 378    /// Clamps a point to the area boundary or interior.
 379    /// </summary>
 380    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 381    public Vector2d ClampPoint(Vector2d point)
 382    {
 27383        return new Vector2d(
 27384            FixedMath.Clamp(point.X, Min.X, Max.X),
 27385            FixedMath.Clamp(point.Y, Min.Y, Max.Y));
 386    }
 387
 388    /// <summary>
 389    /// Projects a point onto this area by clamping it to the boundary or interior.
 390    /// </summary>
 391    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1392    public Vector2d ProjectPoint(Vector2d point) => ClampPoint(point);
 393
 394    #endregion
 395
 396    #region Deconstruction
 397
 398    /// <summary>
 399    /// Deconstructs the area into normalized minimum and maximum corners.
 400    /// </summary>
 401    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 402    public void Deconstruct(out Vector2d min, out Vector2d max)
 403    {
 1404        min = Min;
 1405        max = Max;
 1406    }
 407
 408    #endregion
 409
 410    #region Equality
 411
 412    /// <inheritdoc />
 413    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 414    public bool Equals(FixedBoundArea other)
 415    {
 34416        return Min == other.Min && Max == other.Max;
 417    }
 418
 419    /// <inheritdoc />
 420    public override bool Equals(object? obj)
 421    {
 2422        return obj is FixedBoundArea other && Equals(other);
 423    }
 424
 425    /// <inheritdoc />
 426    public override int GetHashCode()
 427    {
 428        unchecked
 429        {
 3430            int hash = 17;
 3431            hash = (hash * 31) + Min.StateHash;
 3432            hash = (hash * 31) + Max.StateHash;
 3433            return hash;
 434        }
 435    }
 436
 437    /// <summary>
 438    /// Determines whether two areas have the same normalized bounds.
 439    /// </summary>
 440    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2441    public static bool operator ==(FixedBoundArea left, FixedBoundArea right) => left.Equals(right);
 442
 443    /// <summary>
 444    /// Determines whether two areas have different normalized bounds.
 445    /// </summary>
 446    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2447    public static bool operator !=(FixedBoundArea left, FixedBoundArea right) => !left.Equals(right);
 448
 449    #endregion
 450
 451    #region Static Operations
 452
 453    /// <summary>
 454    /// Creates a new area that contains both input areas.
 455    /// </summary>
 456    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 457    public static FixedBoundArea Union(FixedBoundArea a, FixedBoundArea b)
 458    {
 1459        return FromMinMax(ComponentMin(a.Min, b.Min), ComponentMax(a.Max, b.Max));
 460    }
 461
 462    #endregion
 463
 464    #region Helpers
 465
 466    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 467    private bool HasPositiveArea()
 468    {
 8469        return Min.X < Max.X && Min.Y < Max.Y;
 470    }
 471
 472    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 473    private static Vector2d ComponentMin(Vector2d a, Vector2d b)
 474    {
 360475        return new Vector2d(FixedMath.Min(a.X, b.X), FixedMath.Min(a.Y, b.Y));
 476    }
 477
 478    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 479    private static Vector2d ComponentMax(Vector2d a, Vector2d b)
 480    {
 360481        return new Vector2d(FixedMath.Max(a.X, b.X), FixedMath.Max(a.Y, b.Y));
 482    }
 483
 484    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 485    private void SetCenterAndHalfSize(Vector2d center, Vector2d halfSize)
 486    {
 21487        if (!Vector2d.TrySubtract(center, halfSize, out Vector2d min)
 21488            || !Vector2d.TryAdd(center, halfSize, out Vector2d max))
 489        {
 4490            throw CreateUnrepresentableBoundsException();
 491        }
 492
 17493        Min = min;
 17494        Max = max;
 17495    }
 496
 497    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 498    private void SetCenterAndHalfSizeClippedToDomain(Vector2d center, Vector2d halfSize)
 499    {
 6500        Vector2d min = center - halfSize;
 6501        Vector2d max = center + halfSize;
 6502        Min = min;
 6503        Max = max;
 6504    }
 505
 506    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 18507    private static Vector2d GetHalfSize(Vector2d size) => new(
 18508        WideGeometry.GetHalfSizeMagnitude(size.X),
 18509        WideGeometry.GetHalfSizeMagnitude(size.Y));
 510
 511    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 7512    private static Vector2d GetScopeMagnitude(Vector2d scope) => new(
 7513        WideGeometry.GetExtentMagnitude(scope.X),
 7514        WideGeometry.GetExtentMagnitude(scope.Y));
 515
 516    private static OverflowException CreateUnrepresentableBoundsException() =>
 4517        new("The centered area places at least one endpoint outside the representable Fixed64 range.");
 518
 519    #endregion
 520
 521    /// <summary>
 522    /// Creates the representable-domain intersection of a centered capsule's
 523    /// tight axis-aligned bounds from its scalar frame rotation.
 524    /// </summary>
 525    /// <remarks>
 526    /// The capsule's local positive Y axis is its center axis. Sine and cosine
 527    /// remain authoritative through the exact finite-axis bound calculation;
 528    /// no rounded normalized world axis is fed back into the geometry.
 529    /// </remarks>
 530    /// <exception cref="ArgumentOutOfRangeException">
 531    /// <paramref name="fullAxisLength"/> or <paramref name="radius"/> is negative.
 532    /// </exception>
 533    public static FixedBoundArea FromCenteredRotatedCapsuleClippedToDomain(
 534        Vector2d center,
 535        Fixed64 rotation,
 536        Fixed64 fullAxisLength,
 537        Fixed64 radius)
 538    {
 6539        if (fullAxisLength < Fixed64.Zero)
 1540            throw new ArgumentOutOfRangeException(nameof(fullAxisLength));
 5541        if (radius < Fixed64.Zero)
 1542            throw new ArgumentOutOfRangeException(nameof(radius));
 543
 4544        Fixed64 axisX = -FixedMath.Sin(rotation);
 4545        Fixed64 axisY = FixedMath.Cos(rotation);
 4546        return FromMinMax(
 4547            new Vector2d(
 4548                WideGeometry.GetCenteredFiniteAxisBoundClippedToDomain(
 4549                    center.X,
 4550                    axisX,
 4551                    fullAxisLength,
 4552                    radius,
 4553                    minimum: true),
 4554                WideGeometry.GetCenteredFiniteAxisBoundClippedToDomain(
 4555                    center.Y,
 4556                    axisY,
 4557                    fullAxisLength,
 4558                    radius,
 4559                    minimum: true)),
 4560            new Vector2d(
 4561                WideGeometry.GetCenteredFiniteAxisBoundClippedToDomain(
 4562                    center.X,
 4563                    axisX,
 4564                    fullAxisLength,
 4565                    radius,
 4566                    minimum: false),
 4567                WideGeometry.GetCenteredFiniteAxisBoundClippedToDomain(
 4568                    center.Y,
 4569                    axisY,
 4570                    fullAxisLength,
 4571                    radius,
 4572                    minimum: false)));
 573    }
 574
 575    /// <summary>
 576    /// Creates the representable-domain intersection of a centered capsule's
 577    /// tight axis-aligned bounds from its full center-axis length.
 578    /// </summary>
 579    /// <param name="center">The center of the capsule's axis segment.</param>
 580    /// <param name="axisDirection">The normalized center-axis direction.</param>
 581    /// <param name="fullAxisLength">The nonnegative full center-axis length.</param>
 582    /// <param name="radius">The nonnegative capsule radius.</param>
 583    /// <remarks>
 584    /// Each exact endpoint is clipped to the scalar domain and rounded outward.
 585    /// Zero length and zero radius are valid degenerate capsules.
 586    /// </remarks>
 587    /// <exception cref="ArgumentException">
 588    /// <paramref name="axisDirection"/> is zero or not normalized.
 589    /// </exception>
 590    /// <exception cref="ArgumentOutOfRangeException">
 591    /// <paramref name="fullAxisLength"/> or <paramref name="radius"/> is negative.
 592    /// </exception>
 593    public static FixedBoundArea FromCenteredCapsuleClippedToDomain(
 594        Vector2d center,
 595        Vector2d axisDirection,
 596        Fixed64 fullAxisLength,
 597        Fixed64 radius)
 598    {
 272599        if (!axisDirection.IsNormalized())
 600        {
 2601            throw new ArgumentException(
 2602                "Finite-axis direction must be normalized.",
 2603                nameof(axisDirection));
 604        }
 270605        if (fullAxisLength < Fixed64.Zero)
 1606            throw new ArgumentOutOfRangeException(nameof(fullAxisLength));
 269607        if (radius < Fixed64.Zero)
 1608            throw new ArgumentOutOfRangeException(nameof(radius));
 609
 268610        return FromMinMax(
 268611            new Vector2d(
 268612                WideGeometry.GetCenteredFiniteAxisBoundClippedToDomain(
 268613                    center.X,
 268614                    axisDirection.X,
 268615                    fullAxisLength,
 268616                    radius,
 268617                    minimum: true),
 268618                WideGeometry.GetCenteredFiniteAxisBoundClippedToDomain(
 268619                    center.Y,
 268620                    axisDirection.Y,
 268621                    fullAxisLength,
 268622                    radius,
 268623                    minimum: true)),
 268624            new Vector2d(
 268625                WideGeometry.GetCenteredFiniteAxisBoundClippedToDomain(
 268626                    center.X,
 268627                    axisDirection.X,
 268628                    fullAxisLength,
 268629                    radius,
 268630                    minimum: false),
 268631                WideGeometry.GetCenteredFiniteAxisBoundClippedToDomain(
 268632                    center.Y,
 268633                    axisDirection.Y,
 268634                    fullAxisLength,
 268635                    radius,
 268636                    minimum: false)));
 637    }
 638}

Methods/Properties

.ctor(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
.ctor(FixedMathSharp.Geometry.FixedBoundArea/BoundingAreaState)
get_Center()
set_Center(FixedMathSharp.Vector2d)
get_Size()
set_Size(FixedMathSharp.Vector2d)
get_Scope()
get_State()
set_State(FixedMathSharp.Geometry.FixedBoundArea/BoundingAreaState)
FromMinMax(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
FromCenterAndSize(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
FromCenterAndScope(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
FromCenterAndSizeClippedToDomain(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
FromCenterAndScopeClippedToDomain(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
FromCenterAndOffsetsClippedToDomain(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
FromRotatedOffsetsClippedToDomain(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
SetMinMax(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
Contains(FixedMathSharp.Vector2d)
Contains(FixedMathSharp.Geometry.FixedBoundArea)
Contains(FixedMathSharp.Geometry.FixedBoundCircle)
Intersects(FixedMathSharp.Geometry.FixedBoundArea)
Intersects(FixedMathSharp.Geometry.FixedBoundCircle)
IntersectsStrict(FixedMathSharp.Geometry.FixedBoundArea)
IntersectsStrict(FixedMathSharp.Geometry.FixedBoundCircle)
ClampPoint(FixedMathSharp.Vector2d)
ProjectPoint(FixedMathSharp.Vector2d)
Deconstruct(FixedMathSharp.Vector2d&,FixedMathSharp.Vector2d&)
Equals(FixedMathSharp.Geometry.FixedBoundArea)
Equals(System.Object)
GetHashCode()
op_Equality(FixedMathSharp.Geometry.FixedBoundArea,FixedMathSharp.Geometry.FixedBoundArea)
op_Inequality(FixedMathSharp.Geometry.FixedBoundArea,FixedMathSharp.Geometry.FixedBoundArea)
Union(FixedMathSharp.Geometry.FixedBoundArea,FixedMathSharp.Geometry.FixedBoundArea)
HasPositiveArea()
ComponentMin(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
ComponentMax(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
SetCenterAndHalfSize(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
SetCenterAndHalfSizeClippedToDomain(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
GetHalfSize(FixedMathSharp.Vector2d)
GetScopeMagnitude(FixedMathSharp.Vector2d)
CreateUnrepresentableBoundsException()
FromCenteredRotatedCapsuleClippedToDomain(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
FromCenteredCapsuleClippedToDomain(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)