< Summary

Line coverage
100%
Covered lines: 463
Uncovered lines: 0
Coverable lines: 463
Total lines: 1892
Line coverage: 100%
Branch coverage
100%
Covered branches: 96
Total branches: 96
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: ToString()100%11100%
File 1: ToString(...)100%11100%
File 1: TryFormat(...)100%1010100%
File 1: ToVector3d(...)100%11100%
File 1: ToVector4d(...)100%11100%
File 1: Deconstruct(...)100%11100%
File 1: Deconstruct(...)100%11100%
File 1: Deconstruct(...)100%11100%
File 1: Deconstruct(...)100%11100%
File 1: ToDegrees(...)100%11100%
File 1: ToRadians(...)100%11100%
File 2: get_Forward()100%11100%
File 2: get_Backward()100%11100%
File 2: get_Right()100%11100%
File 2: get_Left()100%11100%
File 2: get_One()100%11100%
File 2: get_Negative()100%11100%
File 2: get_Zero()100%11100%
File 2: .ctor(...)100%11100%
File 2: .ctor(...)100%11100%
File 2: FromDouble(...)100%11100%
File 2: get_RotatedRight()100%11100%
File 2: get_RotatedLeft()100%11100%
File 2: get_RightHandNormal()100%11100%
File 2: get_LeftHandNormal()100%11100%
File 2: get_Normalized()100%11100%
File 2: get_Magnitude()100%11100%
File 2: get_MagnitudeSquared()100%11100%
File 2: get_LongStateHash()100%11100%
File 2: get_StateHash()100%11100%
File 2: get_Item(...)100%44100%
File 2: set_Item(...)100%44100%
File 2: Set(...)100%11100%
File 2: AddInPlace(...)100%11100%
File 2: AddInPlace(...)100%11100%
File 2: AddInPlace(...)100%11100%
File 2: SubtractInPlace(...)100%11100%
File 2: SubtractInPlace(...)100%11100%
File 2: SubtractInPlace(...)100%11100%
File 2: MultiplyInPlace(...)100%11100%
File 2: MultiplyInPlace(...)100%11100%
File 2: MultiplyInPlace(...)100%11100%
File 2: DivideInPlace(...)100%11100%
File 2: DivideInPlace(...)100%11100%
File 2: DivideInPlace(...)100%11100%
File 2: NormalizeInPlace()100%11100%
File 2: NormalizeInPlace(...)100%1212100%
File 2: IsNormalized()100%22100%
File 2: TryGetMagnitudeCeiling(...)100%11100%
File 2: LerpInPlace(...)100%11100%
File 2: LerpInPlace(...)100%44100%
File 2: Lerp(...)100%11100%
File 2: RotateInPlace(...)100%11100%
File 2: Rotated(...)100%11100%
File 2: Rotated(...)100%11100%
File 2: RotateInverse(...)100%11100%
File 2: RotateRightInPlace()100%11100%
File 2: RotateLeftInPlace()100%11100%
File 2: ReflectInPlace(...)100%11100%
File 2: ReflectInPlace(...)100%11100%
File 2: ReflectInPlace(...)100%11100%
File 2: Reflected(...)100%11100%
File 2: Reflected(...)100%11100%
File 2: Dot(...)100%11100%
File 2: Dot(...)100%11100%
File 2: CrossProduct(...)100%11100%
File 2: CrossProduct(...)100%11100%
File 2: Distance(...)100%22100%
File 2: Distance(...)100%11100%
File 2: DistanceSquared(...)100%11100%
File 2: DistanceSquared(...)100%11100%
File 3: EqualsZero()100%11100%
File 3: NotZero()100%11100%
File 3: AllComponentsGreaterThanEpsilon()100%22100%
File 3: Equals(...)100%22100%
File 3: Equals(...)100%22100%
File 3: Equals(...)100%11100%
File 3: GetHashCode()100%11100%
File 3: GetHashCode(...)100%11100%
File 3: CompareTo(...)100%11100%
File 4: op_Addition(...)100%11100%
File 4: op_Addition(...)100%11100%
File 4: op_Addition(...)100%11100%
File 4: op_Addition(...)100%11100%
File 4: op_Addition(...)100%11100%
File 4: op_Subtraction(...)100%11100%
File 4: op_Subtraction(...)100%11100%
File 4: op_Subtraction(...)100%11100%
File 4: op_Subtraction(...)100%11100%
File 4: op_Subtraction(...)100%11100%
File 4: op_UnaryNegation(...)100%11100%
File 4: op_Multiply(...)100%11100%
File 4: op_Multiply(...)100%11100%
File 4: op_Multiply(...)100%11100%
File 4: op_Division(...)100%11100%
File 4: op_Equality(...)100%11100%
File 4: op_Inequality(...)100%11100%
File 5: Add(...)100%11100%
File 5: TryAdd(...)100%44100%
File 5: Subtract(...)100%11100%
File 5: TrySubtract(...)100%44100%
File 5: TryAddSubtract(...)100%44100%
File 5: TrySubtractSums(...)100%22100%
File 5: CompareProjection(...)100%11100%
File 5: Multiply(...)100%11100%
File 5: Multiply(...)100%11100%
File 5: Divide(...)100%11100%
File 5: Divide(...)100%11100%
File 5: Clamp(...)100%11100%
File 5: GetNormalized(...)100%1212100%
File 5: GetScaleNormalized(...)100%11100%
File 5: TryTransformScaledPoint(...)100%11100%
File 5: TryTransformScaledPoint(...)100%11100%
File 5: TryInverseTransformScaledPoint(...)100%11100%
File 5: TryComposeScaledLocalPoints(...)100%11100%
File 5: GetDirection(...)100%11100%
File 5: GetMagnitude(...)100%11100%
File 5: TryGetMagnitude(...)100%11100%
File 5: TryGetMagnitude(...)100%88100%
File 5: TryGetDistance(...)100%11100%
File 5: CompareMagnitudeSquared(...)100%11100%
File 5: Abs(...)100%11100%
File 5: Sign(...)100%11100%
File 5: TryGetWeightedAverage(...)100%11100%
File 5: GetAverage(...)100%22100%
File 5: CreateRotation(...)100%11100%
File 5: Lerp(...)100%11100%
File 5: BarycentricCoordinates(...)100%11100%
File 5: Distance(...)100%11100%
File 5: DistanceSquared(...)100%11100%
File 5: ClosestPointOnLineSegment(...)100%11100%
File 5: GetClosestPointOnLineSegmentParameter(...)100%66100%
File 5: CompareDistanceSquared(...)100%11100%
File 5: OrientationSign(...)100%11100%
File 5: ForwardDirection(...)100%11100%
File 5: Dot(...)100%11100%
File 5: CrossProduct(...)100%11100%
File 5: Rotate(...)100%11100%
File 5: TryRotate(...)100%22100%
File 5: TryTransformPoint(...)100%22100%
File 5: TryTransformPoint(...)100%11100%
File 5: TryGetRelativeOffset(...)100%22100%
File 5: TryGetRelativeOffset(...)100%44100%

File(s)

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Numerics/Vectors/Vector2d.Conversions.cs

#LineLine coverage
 1//=======================================================================
 2// Vector2d.Conversions.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.Globalization;
 10using System.Runtime.CompilerServices;
 11
 12namespace FixedMathSharp;
 13
 14/// <content>
 15/// Conversion, formatting, and deconstruction utilities for <see cref="Vector2d"/>.
 16/// </content>
 17public partial struct Vector2d
 18{
 19    /// <summary>
 20    /// Returns a string representation of this vector.
 21    /// </summary>
 22    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2923    public override readonly string ToString() => ToString(null, CultureInfo.InvariantCulture);
 24
 25    /// <summary>
 26    /// Returns a string representation of this vector.
 27    /// </summary>
 28    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 29    public readonly string ToString(string? format, IFormatProvider? formatProvider)
 30    {
 3031        Vector2d value = this;
 3032        return FixedDiagnosticsFormatter.ToString((Span<char> destination, out int charsWritten) =>
 3033            value.TryFormat(destination, out charsWritten, format.AsSpan(), formatProvider));
 34    }
 35
 36    /// <summary>
 37    /// Formats this vector into the provided destination buffer.
 38    /// </summary>
 39    public readonly bool TryFormat(
 40        Span<char> destination,
 41        out int charsWritten,
 42        ReadOnlySpan<char> format,
 43        IFormatProvider? provider)
 44    {
 927945        int written = 0;
 927946        if (!FixedDiagnosticsFormatter.Append('(', destination, ref written) ||
 927947            !FixedDiagnosticsFormatter.Append(X, destination, ref written, format, provider) ||
 927948            !FixedDiagnosticsFormatter.Append(", ", destination, ref written) ||
 927949            !FixedDiagnosticsFormatter.Append(Y, destination, ref written, format, provider) ||
 927950            !FixedDiagnosticsFormatter.Append(')', destination, ref written))
 51        {
 1352            charsWritten = 0;
 1353            return false;
 54        }
 55
 926656        charsWritten = written;
 926657        return true;
 58    }
 59
 60    /// <summary>
 61    /// Converts this <see cref="Vector2d"/> to a <see cref="Vector3d"/>,
 62    /// mapping the Y component of this vector to the Z axis in the resulting vector.
 63    /// </summary>
 64    /// <param name="z">The value to assign to the Y axis of the resulting <see cref="Vector3d"/>.</param>
 65    /// <returns>
 66    /// A new <see cref="Vector3d"/> where (X, Y) from this <see cref="Vector2d"/>
 67    /// become (X, Z) in the resulting vector, with the provided Z parameter assigned to Y.
 68    /// </returns>
 69    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 221170    public Vector3d ToVector3d(Fixed64 z) => new(X, z, Y);
 71
 72    /// <summary>
 73    /// Converts this <see cref="Vector2d"/> to a <see cref="Vector4d"/> with explicit Z and W components.
 74    /// </summary>
 75    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 176    public Vector4d ToVector4d(Fixed64 z, Fixed64 w) => new(X, Y, z, w);
 77
 78    /// <summary>
 79    /// Deconstructs the Vector2d into its two Fixed64 components.
 80    /// </summary>
 81    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 82    public void Deconstruct(out Fixed64 x, out Fixed64 y)
 83    {
 184        x = X;
 185        y = Y;
 186    }
 87
 88    /// <summary>
 89    /// Deconstructs the Vector2d into its two int components.
 90    /// </summary>
 91    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 92    public void Deconstruct(out int x, out int y)
 93    {
 194        x = X.RoundToInt();
 195        y = Y.RoundToInt();
 196    }
 97
 98    /// <summary>
 99    /// Deconstructs the Vector2d into its two long components.
 100    /// </summary>
 101    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 102    public void Deconstruct(out long x, out long y)
 103    {
 1104        x = X.m_rawValue;
 1105        y = Y.m_rawValue;
 1106    }
 107
 108    /// <summary>
 109    /// Deconstructs the Vector2d into its two double components.
 110    /// </summary>
 111    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 112    public void Deconstruct(out double x, out double y)
 113    {
 1114        x = (double)X;
 1115        y = (double)Y;
 1116    }
 117
 118    /// <summary>
 119    /// Converts each component of the vector from radians to degrees.
 120    /// </summary>
 121    /// <param name="radians">The vector with components in radians.</param>
 122    /// <returns>A new vector with components converted to degrees.</returns>
 123    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 124    public static Vector2d ToDegrees(Vector2d radians) =>
 1125        new(FixedMath.RadToDeg(radians.X),
 1126            FixedMath.RadToDeg(radians.Y));
 127
 128    /// <summary>
 129    /// Converts each component of the vector from degrees to radians.
 130    /// </summary>
 131    /// <param name="degrees">The vector with components in degrees.</param>
 132    /// <returns>A new vector with components converted to radians.</returns>
 133    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 134    public static Vector2d ToRadians(Vector2d degrees) =>
 1135        new(FixedMath.DegToRad(degrees.X),
 1136            FixedMath.DegToRad(degrees.Y));
 137}

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Numerics/Vectors/Vector2d.cs

#LineLine coverage
 1//=======================================================================
 2// Vector2d.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.Collections.Generic;
 10using System.Runtime.CompilerServices;
 11using System.Text.Json.Serialization;
 12using FixedMathSharp.Geometry;
 13using MemoryPack;
 14
 15namespace FixedMathSharp;
 16
 17/// <summary>
 18/// Represents a 2D vector with fixed-point precision, offering a range of mathematical operations
 19/// and transformations such as rotation, scaling, reflection, and interpolation.
 20/// </summary>
 21/// <remarks>
 22/// The Vector2d struct is designed for applications that require precise numerical operations,
 23/// such as games, simulations, or physics engines. It provides methods for common vector operations
 24/// like addition, subtraction, dot product, cross product, distance calculations, and rotation.
 25///
 26/// FixedMathSharp treats <see cref="Vector2d"/> as plane math: <c>+X</c> is right and
 27/// <c>+Y</c> is the named <see cref="Forward"/> direction. Polar angle helpers are separate:
 28/// <see cref="ForwardDirection(Fixed64)"/> returns <c>+X</c> at angle zero.
 29///
 30/// Use Cases:
 31/// - Modeling 2D positions, directions, and velocities in fixed-point math environments.
 32/// - Performing vector transformations, including rotations and reflections.
 33/// - Handling interpolation and distance calculations in physics or simulation systems.
 34/// - Useful for fixed-point math scenarios where floating-point precision is insufficient or not desired.
 35/// </remarks>
 36[Serializable]
 37[MemoryPackable]
 38public partial struct Vector2d : IEquatable<Vector2d>, IComparable<Vector2d>, IEqualityComparer<Vector2d>, IFormattable
 39#if NET8_0_OR_GREATER
 40    , ISpanFormattable
 41#endif
 42{
 43    #region Static Readonly Fields
 44
 45    /// <summary>
 46    /// The named 2D plane forward direction (0, 1).
 47    /// </summary>
 48    /// <remarks>
 49    /// This is distinct from polar angle math: <see cref="ForwardDirection(Fixed64)"/> returns
 50    /// <see cref="Right"/> when its angle argument is zero.
 51    /// </remarks>
 32552    public static Vector2d Forward => new(0, 1);
 53
 54    /// <summary>
 55    /// (0, -1)
 56    /// </summary>
 557    public static Vector2d Backward => new(0, -1);
 58
 59    /// <summary>
 60    /// The named 2D plane right direction (1, 0).
 61    /// </summary>
 85162    public static Vector2d Right => new(1, 0);
 63
 64    /// <summary>
 65    /// (-1, 0)
 66    /// </summary>
 5367    public static Vector2d Left => new(-1, 0);
 68
 69    /// <summary>
 70    /// (1, 1)
 71    /// </summary>
 72172    public static Vector2d One => new(1, 1);
 73
 74    /// <summary>
 75    /// (-1, -1)
 76    /// </summary>
 477    public static Vector2d Negative => new(-1, -1);
 78
 79    /// <summary>
 80    /// (0, 0)
 81    /// </summary>
 19576782    public static Vector2d Zero => new(0, 0);
 83
 84    #endregion
 85    #region Fields
 86
 87    /// <summary>
 88    /// The X component of the vector.
 89    /// </summary>
 90    [JsonInclude]
 91    [MemoryPackOrder(0)]
 92    public Fixed64 X;
 93
 94    /// <summary>
 95    /// The Y component of the vector.
 96    /// </summary>
 97    [JsonInclude]
 98    [MemoryPackOrder(1)]
 99    public Fixed64 Y;
 100
 101    #endregion
 102    #region Constructors
 103
 104    /// <summary>
 105    /// Initializes a new instance of the Vector2d structure using integer values for the X and Y components.
 106    /// </summary>
 107    /// <param name="xInt">The X component of the vector, specified as an integer.</param>
 108    /// <param name="yInt">The Y component of the vector, specified as an integer.</param>
 398362109    public Vector2d(int xInt, int yInt) : this((Fixed64)xInt, (Fixed64)yInt) { }
 110
 111    /// <summary>
 112    /// Initializes a new instance of the Vector2d structure with the specified X and Y components.
 113    /// </summary>
 114    /// <param name="x">The value to assign to the X component of the vector.</param>
 115    /// <param name="y">The value to assign to the Y component of the vector.</param>
 116    [JsonConstructor]
 117    public Vector2d(Fixed64 x, Fixed64 y)
 118    {
 227146119        X = x;
 227146120        Y = y;
 227146121    }
 122
 123    /// <summary>
 124    /// Initializes a new instance of the Vector2d structure using double-precision floating-point values for the X and 
 125    /// </summary>
 126    /// <remarks>
 127    /// Components are converted through <see cref="Fixed64.FromDouble(double)"/>, so non-finite
 128    /// values throw <see cref="ArgumentOutOfRangeException"/> and finite values outside the Q32.32
 129    /// range throw <see cref="OverflowException"/>.
 130    /// </remarks>
 131    public static Vector2d FromDouble(double xDoub, double yDoub) =>
 12132        new(Fixed64.FromDouble(xDoub), Fixed64.FromDouble(yDoub));
 133
 134    #endregion
 135    #region Properties
 136
 137    /// <summary>
 138    /// Rotates the vector to the right (90 degrees clockwise).
 139    /// </summary>
 140    [JsonIgnore]
 141    [MemoryPackIgnore]
 142    public Vector2d RotatedRight
 143    {
 144        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1145        get => new(Y, -X);
 146    }
 147
 148    /// <summary>
 149    /// Rotates the vector to the left (90 degrees counterclockwise).
 150    /// </summary>
 151    [JsonIgnore]
 152    [MemoryPackIgnore]
 153    public Vector2d RotatedLeft
 154    {
 155        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1156        get => new(-Y, X);
 157    }
 158
 159    /// <summary>
 160    /// Gets the right-hand (counter-clockwise) normal vector.
 161    /// </summary>
 162    [JsonIgnore]
 163    [MemoryPackIgnore]
 164    public Vector2d RightHandNormal
 165    {
 166        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 55167        get => new(-Y, X);
 168    }
 169
 170    /// <summary>
 171    /// Gets the left-hand (clockwise) normal vector.
 172    /// </summary>
 173    [JsonIgnore]
 174    [MemoryPackIgnore]
 175    public Vector2d LeftHandNormal
 176    {
 177        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1178        get => new(Y, -X);
 179    }
 180
 181    /// <inheritdoc cref="GetNormalized(Vector2d)"/>
 182    [JsonIgnore]
 183    [MemoryPackIgnore]
 184    public Vector2d Normalized
 185    {
 186        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 80187        get => GetNormalized(this);
 188    }
 189
 190    /// <summary>
 191    /// Returns the actual length of this vector (RO).
 192    /// </summary>
 193    [JsonIgnore]
 194    [MemoryPackIgnore]
 195    public Fixed64 Magnitude
 196    {
 197        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 47198        get => GetMagnitude(this);
 199    }
 200
 201    /// <summary>
 202    /// Returns the square magnitude of the vector (avoids calculating the square root).
 203    /// </summary>
 204    [JsonIgnore]
 205    [MemoryPackIgnore]
 206    public Fixed64 MagnitudeSquared
 207    {
 208        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 40209        get => X * X + Y * Y;
 210    }
 211
 212    /// <summary>
 213    /// Returns a long hash of the vector based on its x and y values.
 214    /// </summary>
 215    [JsonIgnore]
 216    [MemoryPackIgnore]
 217    public long LongStateHash
 218    {
 219        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 51220        get => X.m_rawValue * 31 + Y.m_rawValue * 7;
 221    }
 222
 223    /// <summary>
 224    /// Returns a hash of the vector based on its state.
 225    /// </summary>
 226    [JsonIgnore]
 227    [MemoryPackIgnore]
 228    public int StateHash
 229    {
 230        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 49231        get => (int)(LongStateHash % int.MaxValue);
 232    }
 233
 234    /// <summary>
 235    /// Gets or sets the vector component at the specified index.
 236    /// </summary>
 237    /// <remarks>
 238    /// This indexer provides array-like access to the vector's components.
 239    /// Index 0 corresponds to the X component, and index 1 corresponds to the Y component.
 240    /// </remarks>
 241    /// <param name="index">The zero-based index of the component to access. Use 0 for the X component and 1 for the Y c
 242    /// <returns>The vector component at the specified index.</returns>
 243    /// <exception cref="IndexOutOfRangeException">Thrown when the index is less than 0 or greater than 1.</exception>
 244    [JsonIgnore]
 245    [MemoryPackIgnore]
 246    public Fixed64 this[int index]
 247    {
 248        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 249        get
 250        {
 8251            return index switch
 8252            {
 3253                0 => X,
 3254                1 => Y,
 2255                _ => throw new IndexOutOfRangeException("Invalid Vector2d index!"),
 8256            };
 257        }
 258        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 259        set
 260        {
 261            switch (index)
 262            {
 263                case 0:
 3264                    X = value;
 3265                    break;
 266                case 1:
 3267                    Y = value;
 3268                    break;
 269                default:
 2270                    throw new IndexOutOfRangeException("Invalid Vector2d index!");
 271            }
 272        }
 273    }
 274
 275    #endregion
 276    #region Methods (Instance)
 277
 278    /// <summary>
 279    /// Set x, y and z components of an existing Vector3.
 280    /// </summary>
 281    /// <param name="newX"></param>
 282    /// <param name="newY"></param>
 283    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 284    public void Set(Fixed64 newX, Fixed64 newY)
 285    {
 1286        X = newX;
 1287        Y = newY;
 1288    }
 289
 290    /// <summary>
 291    /// Adds the specified values to the components of the vector in place and returns the modified vector.
 292    /// </summary>
 293    /// <param name="xAmount">The amount to add to the x component.</param>
 294    /// <param name="yAmount">The amount to add to the y component.</param>
 295    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 296    public Vector2d AddInPlace(Fixed64 xAmount, Fixed64 yAmount)
 297    {
 5298        X += xAmount;
 5299        Y += yAmount;
 5300        return this;
 301    }
 302
 303    /// <summary>
 304    /// Adds the specified values to the components of the vector in place and returns the modified vector.
 305    /// </summary>
 306    /// <param name="amount">The amount to add to the components.</param>
 307    /// <returns>The modified vector after addition.</returns>
 308    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2309    public Vector2d AddInPlace(Fixed64 amount) => AddInPlace(amount, amount);
 310
 311    /// <inheritdoc cref="AddInPlace(Fixed64, Fixed64)"/>
 312    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2313    public Vector2d AddInPlace(Vector2d other) => AddInPlace(other.X, other.Y);
 314
 315    /// <summary>
 316    /// Subtracts the specified values from the components of the vector in place and returns the modified vector.
 317    /// </summary>
 318    /// <param name="xAmount">The amount to subtract from the x component.</param>
 319    /// <param name="yAmount">The amount to subtract from the y component.</param>
 320    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 321    public Vector2d SubtractInPlace(Fixed64 xAmount, Fixed64 yAmount)
 322    {
 5323        X -= xAmount;
 5324        Y -= yAmount;
 5325        return this;
 326    }
 327
 328    /// <summary>
 329    /// Subtracts the specified value from all components of the vector in place and returns the modified vector.
 330    /// </summary>
 331    /// <param name="amount">The amount to subtract from each component.</param>
 332    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 3333    public Vector2d SubtractInPlace(Fixed64 amount) => SubtractInPlace(amount, amount);
 334
 335    /// <summary>
 336    /// Subtracts the specified vector from the components of the vector in place and returns the modified vector.
 337    /// </summary>
 338    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1339    public Vector2d SubtractInPlace(Vector2d other) => SubtractInPlace(other.X, other.Y);
 340
 341    /// <summary>
 342    /// Multiplies the components of the vector by the specified x and y factors in place and returns the modified vecto
 343    /// </summary>
 344    /// <param name="factorX">The factor to multiply the x component by.</param>
 345    /// <param name="factorY">The factor to multiply the y component by.</param>
 346    /// <returns>The modified vector after multiplication.</returns>
 347    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 348    public Vector2d MultiplyInPlace(Fixed64 factorX, Fixed64 factorY)
 349    {
 6350        X *= factorX;
 6351        Y *= factorY;
 6352        return this;
 353    }
 354
 355    /// <summary>
 356    /// Multiplies the components of the vector by the specified scalar factor in place and returns the modified vector.
 357    /// </summary>
 358    /// <param name="factor">The scalar factor to multiply each component by.</param>
 359    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 3360    public Vector2d MultiplyInPlace(Fixed64 factor) => MultiplyInPlace(factor, factor);
 361
 362    /// <summary>
 363    /// Multiplies each component of the vector by the corresponding component of the given vector in place and returns 
 364    /// </summary>
 365    /// <param name="factor">The vector containing the multiplication factors for each component.</param>
 366    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2367    public Vector2d MultiplyInPlace(Vector2d factor) => MultiplyInPlace(factor.X, factor.Y);
 368
 369    /// <summary>
 370    /// Divides the components of the vector by the specified x and y divisors in place and returns the modified vector.
 371    /// </summary>
 372    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 373    public Vector2d DivideInPlace(Fixed64 divisorX, Fixed64 divisorY)
 374    {
 4375        X /= divisorX;
 4376        Y /= divisorY;
 4377        return this;
 378    }
 379
 380    /// <summary>
 381    /// Divides each component of the vector by the specified scalar divisor in place and returns the modified vector.
 382    /// </summary>
 383    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1384    public Vector2d DivideInPlace(Fixed64 divisor) => DivideInPlace(divisor, divisor);
 385
 386    /// <summary>
 387    /// Divides each component of the vector by the corresponding component of the given vector in place and returns the
 388    /// </summary>
 389    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2390    public Vector2d DivideInPlace(Vector2d divisor) => DivideInPlace(divisor.X, divisor.Y);
 391
 392    /// <summary>
 393    /// Normalizes this vector in place, making its magnitude (length) equal to 1, and returns the modified vector.
 394    /// </summary>
 395    /// <remarks>
 396    /// If the vector is zero-length or already normalized, no operation is performed.
 397    /// This method modifies the current vector in place and supports method chaining.
 398    /// </remarks>
 399    /// <returns>The normalized vector.</returns>
 400    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 5401    public Vector2d NormalizeInPlace() => this = GetNormalized(this);
 402
 403    /// <summary>
 404    /// Normalizes this vector in place and outputs its original magnitude.
 405    /// </summary>
 406    /// <param name="mag">The original magnitude of the vector before normalization.</param>
 407    /// <remarks>
 408    /// If the vector is zero-length or already normalized, no operation is performed, but the original magnitude will s
 409    /// </remarks>
 410    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 411    public Vector2d NormalizeInPlace(out Fixed64 mag)
 412    {
 16413        Vector2d source = this;
 16414        bool magnitudeIsRepresentable = TryGetMagnitude(
 16415            source,
 16416            out mag,
 16417            out bool isNormalized);
 418
 419        // If magnitude is zero, return a zero vector to avoid divide-by-zero errors
 16420        if (mag == Fixed64.Zero)
 421        {
 1422            X = Fixed64.Zero;
 1423            Y = Fixed64.Zero;
 1424            return this;
 425        }
 426
 15427        if (isNormalized)
 1428            return this;
 429
 14430        if (!magnitudeIsRepresentable || mag == Fixed64.One)
 1431            return this = WideNormalization.GetNormalized(source);
 432
 13433        if (mag <= FixedMath.ScaleSafeMagnitudeThreshold)
 2434            return this = GetScaleNormalized(source);
 435
 11436        X = FixedMath.FastDiv(X, mag);
 11437        Y = FixedMath.FastDiv(Y, mag);
 438
 11439        return IsNormalized()
 11440            ? this
 11441            : this = WideNormalization.GetNormalized(source);
 442    }
 443
 444    /// <summary>
 445    /// Checks whether this nonzero vector's squared magnitude is within epsilon of one.
 446    /// </summary>
 447    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 448    public readonly bool IsNormalized()
 449    {
 19907450        Fixed64 squaredMagnitude = X * X + Y * Y;
 19907451        return squaredMagnitude != Fixed64.Zero
 19907452            && FixedMath.Abs(squaredMagnitude - Fixed64.One) <= Fixed64.Epsilon;
 453    }
 454
 455    /// <summary>
 456    /// Attempts to return this vector's magnitude rounded outward to the
 457    /// smallest containing Q32.32 value.
 458    /// </summary>
 459    /// <returns>
 460    /// <see langword="false"/> only when the final ceiling exceeds the
 461    /// positive <see cref="Fixed64"/> domain.
 462    /// </returns>
 463    public readonly bool TryGetMagnitudeCeiling(
 464        out Fixed64 magnitude) =>
 2465        WideGeometry.TryGetMagnitudeCeiling(
 2466            X,
 2467            Y,
 2468            Fixed64.Zero,
 2469            out magnitude);
 470
 471    /// <summary>
 472    /// Linearly interpolates this vector toward the target vector by the specified amount.
 473    /// </summary>
 474    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 475    public Vector2d LerpInPlace(Vector2d target, Fixed64 amount)
 476    {
 3477        LerpInPlace(target.X, target.Y, amount);
 3478        return this;
 479    }
 480
 481    /// <summary>
 482    /// Linearly interpolates this vector toward the target values by the specified amount.
 483    /// </summary>
 484    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 485    public Vector2d LerpInPlace(Fixed64 targetx, Fixed64 targety, Fixed64 amount)
 486    {
 5487        if (amount >= Fixed64.One)
 488        {
 1489            X = targetx;
 1490            Y = targety;
 491        }
 4492        else if (amount > Fixed64.Zero)
 493        {
 3494            X = FixedMath.Lerp(X, targetx, amount);
 3495            Y = FixedMath.Lerp(Y, targety, amount);
 496        }
 5497        return this;
 498    }
 499
 500    /// <summary>
 501    /// Returns a new vector that is the result of linear interpolation toward the target by the specified amount.
 502    /// </summary>
 503    public Vector2d Lerp(Vector2d target, Fixed64 amount)
 504    {
 2505        Vector2d vec = this;
 2506        vec.LerpInPlace(target.X, target.Y, amount);
 2507        return vec;
 508    }
 509
 510    /// <summary>
 511    /// Rotates this vector by the specified cosine and sine values (counter-clockwise).
 512    /// </summary>
 513    public Vector2d RotateInPlace(Fixed64 cos, Fixed64 sin)
 514    {
 4515        Fixed64 temp1 = X * cos - Y * sin;
 4516        Y = X * sin + Y * cos;
 4517        X = temp1;
 4518        return this;
 519    }
 520
 521    /// <summary>
 522    /// Returns a new vector that is the result of rotating this vector by the specified cosine and sine values.
 523    /// </summary>
 524    public Vector2d Rotated(Fixed64 cos, Fixed64 sin)
 525    {
 2526        Vector2d vec = this;
 2527        vec.RotateInPlace(cos, sin);
 2528        return vec;
 529    }
 530
 531    /// <summary>
 532    /// Rotates this vector using another vector representing the cosine and sine of the rotation angle.
 533    /// </summary>
 534    /// <param name="rotation">The vector containing the cosine and sine values for rotation.</param>
 535    /// <returns>A new vector representing the result of the rotation.</returns>
 1536    public Vector2d Rotated(Vector2d rotation) => Rotated(rotation.X, rotation.Y);
 537
 538    /// <summary>
 539    /// Rotates this vector in the inverse direction using cosine and sine values.
 540    /// </summary>
 541    /// <param name="cos">The cosine of the rotation angle.</param>
 542    /// <param name="sin">The sine of the rotation angle.</param>
 1543    public void RotateInverse(Fixed64 cos, Fixed64 sin) => RotateInPlace(cos, -sin);
 544
 545    /// <summary>
 546    /// Rotates this vector 90 degrees to the right (clockwise).
 547    /// </summary>
 548    public Vector2d RotateRightInPlace()
 549    {
 1550        Fixed64 temp1 = X;
 1551        X = Y;
 1552        Y = -temp1;
 1553        return this;
 554    }
 555
 556    /// <summary>
 557    /// Rotates this vector 90 degrees to the left (counterclockwise).
 558    /// </summary>
 559    public Vector2d RotateLeftInPlace()
 560    {
 1561        Fixed64 temp1 = X;
 1562        X = -Y;
 1563        Y = temp1;
 1564        return this;
 565    }
 566
 567    /// <summary>
 568    /// Reflects this vector across the specified axis vector.
 569    /// </summary>
 1570    public Vector2d ReflectInPlace(Vector2d axis) => ReflectInPlace(axis.X, axis.Y);
 571
 572    /// <summary>
 573    /// Reflects this vector across the specified x and y axis.
 574    /// </summary>
 575    public Vector2d ReflectInPlace(Fixed64 axisX, Fixed64 axisY)
 576    {
 4577        Fixed64 projection = Dot(axisX, axisY);
 4578        return ReflectInPlace(axisX, axisY, projection);
 579    }
 580
 581    /// <summary>
 582    /// Reflects this vector across the specified axis using the provided projection of this vector onto the axis.
 583    /// </summary>
 584    /// /// <param name="axisX">The x component of the axis to reflect across.</param>
 585    /// <param name="axisY">The y component of the axis to reflect across.</param>
 586    /// <param name="projection">The precomputed projection of this vector onto the reflection axis.</param>
 587    public Vector2d ReflectInPlace(Fixed64 axisX, Fixed64 axisY, Fixed64 projection)
 588    {
 5589        Fixed64 temp1 = axisX * projection;
 5590        Fixed64 temp2 = axisY * projection;
 5591        X = temp1 + temp1 - X;
 5592        Y = temp2 + temp2 - Y;
 5593        return this;
 594    }
 595
 596    /// <summary>
 597    /// Reflects this vector across the specified x and y axis.
 598    /// </summary>
 599    /// <returns>A new vector representing the result of the reflection.</returns>
 600    public Vector2d Reflected(Fixed64 axisX, Fixed64 axisY)
 601    {
 2602        Vector2d vec = this;
 2603        vec.ReflectInPlace(axisX, axisY);
 2604        return vec;
 605    }
 606
 607    /// <summary>
 608    /// Reflects this vector across the specified axis vector.
 609    /// </summary>
 610    /// <returns>A new vector representing the result of the reflection.</returns>
 1611    public Vector2d Reflected(Vector2d axis) => Reflected(axis.X, axis.Y);
 612
 613    /// <summary>
 614    /// Returns the dot product of this vector with another vector.
 615    /// </summary>
 616    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 223617    public Fixed64 Dot(Fixed64 otherX, Fixed64 otherY) => X * otherX + Y * otherY;
 618
 619    /// <summary>
 620    /// Returns the dot product of this vector with another vector.
 621    /// </summary>
 622    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2623    public Fixed64 Dot(Vector2d other) => Dot(other.X, other.Y);
 624
 625    /// <summary>
 626    /// Computes the cross product magnitude of this vector with another vector.
 627    /// </summary>
 628    /// <param name="otherX">The X component of the other vector.</param>
 629    /// <param name="otherY">The Y component of the other vector.</param>
 630    /// <returns>The cross product magnitude.</returns>
 631    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2632    public Fixed64 CrossProduct(Fixed64 otherX, Fixed64 otherY) => X * otherY - Y * otherX;
 633
 634    /// <inheritdoc cref="CrossProduct(Fixed64, Fixed64)"/>
 635    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2636    public Fixed64 CrossProduct(Vector2d other) => CrossProduct(other.X, other.Y);
 637
 638    /// <summary>
 639    /// Returns the distance between this vector and another vector specified by its components.
 640    /// </summary>
 641    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 642    public Fixed64 Distance(Fixed64 otherX, Fixed64 otherY)
 643    {
 5644        Fixed64 deltaX = X - otherX;
 5645        Fixed64 deltaY = Y - otherY;
 5646        Fixed64 squareSum = deltaX * deltaX + deltaY * deltaY;
 5647        return squareSum == Fixed64.MaxValue
 5648            ? FixedMath.GetScaledMagnitude(deltaX, deltaY, Fixed64.Zero, Fixed64.Zero)
 5649            : FixedMath.Sqrt(squareSum);
 650    }
 651
 652    /// <summary>
 653    /// Returns the distance between this vector and another vector.
 654    /// </summary>
 655    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 5656    public Fixed64 Distance(Vector2d other) => Distance(other.X, other.Y);
 657
 658    /// <summary>
 659    /// Calculates the squared distance between two vectors, avoiding the need for a square root operation.
 660    /// </summary>
 661    /// <returns>The squared distance between the two vectors.</returns>
 662    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 663    public Fixed64 DistanceSquared(Fixed64 otherX, Fixed64 otherY)
 664    {
 49665        Fixed64 temp1 = X - otherX;
 49666        temp1 *= temp1;
 49667        Fixed64 temp2 = Y - otherY;
 49668        temp2 *= temp2;
 49669        return temp1 + temp2;
 670    }
 671
 672    /// <summary>
 673    /// Calculates the squared distance between two vectors, avoiding the need for a square root operation.
 674    /// </summary>
 675    /// <returns>The squared distance between the two vectors.</returns>
 676    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 49677    public Fixed64 DistanceSquared(Vector2d other) => DistanceSquared(other.X, other.Y);
 678
 679    #endregion
 680}

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Numerics/Vectors/Vector2d.Equality.cs

#LineLine coverage
 1//=======================================================================
 2// Vector2d.Equality.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.Runtime.CompilerServices;
 9
 10namespace FixedMathSharp;
 11
 12/// <content>
 13/// Equality, hashing, and comparison logic for <see cref="Vector2d"/>.
 14/// </content>
 15public partial struct Vector2d
 16{
 17    /// <summary>
 18    /// Are all components of this vector equal to zero?
 19    /// </summary>
 20    /// <returns></returns>
 21    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 522    public bool EqualsZero() => Equals(Zero);
 23
 24    /// <summary>
 25    /// Determines whether the current value is not equal to zero.
 26    /// </summary>
 27    /// <returns>true if the value is not zero; otherwise, false.</returns>
 28    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 129    public bool NotZero() => !EqualsZero();
 30
 31    /// <summary>
 32    /// Checks whether all components are strictly greater than <see cref="Fixed64.Epsilon"/>.
 33    /// </summary>
 34    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 35    public bool AllComponentsGreaterThanEpsilon()
 36    {
 237        return X.Abs() > Fixed64.Epsilon && Y.Abs() > Fixed64.Epsilon;
 38    }
 39
 40    /// <inheritdoc/>
 41    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 642    public override bool Equals(object? obj) => obj is Vector2d other && Equals(other);
 43
 44    /// <inheritdoc/>
 45    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 301946    public bool Equals(Vector2d other) => other.X == X && other.Y == Y;
 47
 48    /// <inheritdoc/>
 249    public bool Equals(Vector2d x, Vector2d y) => x.Equals(y);
 50
 51    /// <summary>
 52    /// Returns a hash code for this instance, which is based on the combined hash codes of the X and Y components.
 53    /// </summary>
 54    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2155    public override int GetHashCode() => StateHash;
 56
 57    /// <inheritdoc/>
 158    public int GetHashCode(Vector2d obj) => obj.GetHashCode();
 59
 60    /// <summary>
 61    /// Compares the current Vector2d instance with another Vector2d based on their squared magnitudes.
 62    /// </summary>
 63    /// <remarks>
 64    /// This comparison uses the squared magnitude of each vector, which avoids the computational
 65    /// cost of calculating the actual magnitude.
 66    /// Use this method when only relative vector lengths are
 67    /// important.
 68    /// </remarks>
 69    /// <param name="other">The Vector2d instance to compare with the current instance.</param>
 70    /// <returns>A value less than zero if this instance is less than <paramref name="other"/>; zero if this instance is
 71    /// <paramref name="other"/>; or a value greater than zero if this instance is greater than <paramref
 72    /// name="other"/>, as determined by their squared magnitudes.</returns>
 173    public int CompareTo(Vector2d other) => MagnitudeSquared.CompareTo(other.MagnitudeSquared);
 74}

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Numerics/Vectors/Vector2d.Operators.cs

#LineLine coverage
 1//=======================================================================
 2// Vector2d.Operators.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.Runtime.CompilerServices;
 9
 10namespace FixedMathSharp;
 11
 12/// <content>
 13/// Operator overloads for <see cref="Vector2d"/>, including arithmetic, negation, and equality operators.
 14/// </content>
 15public partial struct Vector2d
 16{
 17    /// <summary>
 18    /// Adds two Vector2d instances component-wise.
 19    /// </summary>
 20    /// <param name="v1">The first vector to add.</param>
 21    /// <param name="v2">The second vector to add.</param>
 22    /// <returns>A new Vector2d whose components are the sums of the corresponding components of v1 and v2.</returns>
 23    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 5924    public static Vector2d operator +(Vector2d v1, Vector2d v2) => new(v1.X + v2.X, v1.Y + v2.Y);
 25
 26    /// <summary>
 27    /// Adds a scalar value to each component of the specified vector and returns the resulting vector.
 28    /// </summary>
 29    /// <param name="v1">The vector to which the scalar value will be added.</param>
 30    /// <param name="mag">The scalar value to add to each component of the vector.</param>
 31    /// <returns>A new Vector2d whose components are the sum of the corresponding components of the input vector and the
 32    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 233    public static Vector2d operator +(Vector2d v1, Fixed64 mag) => new(v1.X + mag, v1.Y + mag);
 34
 35    /// <inheritdoc cref="operator +(Vector2d, Fixed64)"/>
 36    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 137    public static Vector2d operator +(Fixed64 mag, Vector2d v1) => v1 + mag;
 38
 39    /// <summary>
 40    /// Adds a Vector2d instance and a tuple representing X and Y components, returning a new Vector2d with the summed
 41    /// values.
 42    /// </summary>
 43    /// <param name="v1">The first vector to add.</param>
 44    /// <param name="v2">A tuple containing the X and Y values to add to the vector.</param>
 45    /// <returns>A new Vector2d whose X and Y components are the sums of the corresponding components of the input vecto
 46    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 247    public static Vector2d operator +(Vector2d v1, (int x, int y) v2) => new(v1.X + v2.x, v1.Y + v2.y);
 48
 49    /// <summary>
 50    /// Adds a tuple representing X and Y components and a Vector2d instance, returning a new Vector2d with the summed
 51    /// values.
 52    /// </summary>
 53    /// <param name="v2">A tuple containing the X and Y values to add to the vector.</param>
 54    /// <param name="v1">The vector to add.</param>
 55    /// <returns>A new Vector2d whose X and Y components are the sums of the corresponding components of the tuple and i
 56    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 157    public static Vector2d operator +((int x, int y) v2, Vector2d v1) => v1 + v2;
 58
 59    /// <summary>
 60    /// Subtracts the components of one Vector2d from another and returns the resulting vector.
 61    /// </summary>
 62    /// <param name="v1">The vector to subtract from.</param>
 63    /// <param name="v2">The vector to subtract.</param>
 64    /// <returns>A Vector2d whose components are the result of subtracting the corresponding components of v2 from v1.</
 65    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 6566    public static Vector2d operator -(Vector2d v1, Vector2d v2) => new(v1.X - v2.X, v1.Y - v2.Y);
 67
 68    /// <summary>
 69    /// Subtracts the specified scalar value from both components of the given vector and returns the resulting vector.
 70    /// </summary>
 71    /// <param name="v1">The vector from which to subtract the scalar value.</param>
 72    /// <param name="mag">The scalar value to subtract from each component of the vector.</param>
 73    /// <returns>A new Vector2d whose components are the result of subtracting the scalar value from the corresponding c
 74    /// of the input vector.</returns>
 75    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 176    public static Vector2d operator -(Vector2d v1, Fixed64 mag) => new(v1.X - mag, v1.Y - mag);
 77
 78    /// <inheritdoc cref="operator -(Vector2d, Fixed64)"/>
 79    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 180    public static Vector2d operator -(Fixed64 mag, Vector2d v1) => new(mag - v1.X, mag - v1.Y);
 81
 82    /// <summary>
 83    /// Subtracts the specified tuple from the given vector and returns the resulting vector.
 84    /// </summary>
 85    /// <param name="v1">The vector from which to subtract the tuple values.</param>
 86    /// <param name="v2">A tuple containing the x and y values to subtract from the vector.</param>
 87    /// <returns>A new Vector2d representing the result of subtracting the tuple values from the original vector.</retur
 88    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 189    public static Vector2d operator -(Vector2d v1, (int x, int y) v2) => new(v1.X - v2.x, v1.Y - v2.y);
 90
 91    /// <summary>
 92    /// Subtracts the specified Vector2d from the given integer tuple and returns the resulting vector.
 93    /// </summary>
 94    /// <param name="v1">A tuple containing the x and y components to subtract from.</param>
 95    /// <param name="v2">The vector whose components are subtracted from the tuple.</param>
 96    /// <returns>A Vector2d representing the result of subtracting the components of v2 from v1.</returns>
 97    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 198    public static Vector2d operator -((int x, int y) v1, Vector2d v2) => new(v1.x - v2.X, v1.y - v2.Y);
 99
 100    /// <summary>
 101    /// Negates the specified vector by reversing the sign of each of its components.
 102    /// </summary>
 103    /// <param name="v1">The vector to negate.</param>
 104    /// <returns>A new Vector2d whose components are the negated values of the input vector.</returns>
 105    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 260106    public static Vector2d operator -(Vector2d v1) => new(v1.X * -Fixed64.One, v1.Y * -Fixed64.One);
 107
 108    /// <summary>
 109    /// Scales the specified vector by the given scalar value.
 110    /// </summary>
 111    /// <param name="v1">The vector to be scaled.</param>
 112    /// <param name="mag">The scalar value by which to multiply each component of the vector.</param>
 113    /// <returns>A new Vector2d whose components are the components of v1 multiplied by mag.</returns>
 114    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1236115    public static Vector2d operator *(Vector2d v1, Fixed64 mag) => new(v1.X * mag, v1.Y * mag);
 116
 117    /// <inheritdoc cref="operator *(Vector2d, Fixed64)"/>
 118    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 5119    public static Vector2d operator *(Fixed64 mag, Vector2d v1) => v1 * mag;
 120
 121    /// <summary>
 122    /// Multiplies two vectors element-wise and returns the resulting vector.
 123    /// </summary>
 124    /// <remarks>Element-wise multiplication multiplies each component of the first vector by the
 125    /// corresponding component of the second vector. This operation is not a dot product or cross product.</remarks>
 126    /// <param name="v1">The first vector to multiply.</param>
 127    /// <param name="v2">The second vector to multiply.</param>
 128    /// <returns>A new Vector2d whose components are the products of the corresponding components of the input vectors.<
 129    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 3130    public static Vector2d operator *(Vector2d v1, Vector2d v2) => new(v1.X * v2.X, v1.Y * v2.Y);
 131
 132    /// <summary>
 133    /// Divides each component of a specified vector by a scalar value.
 134    /// </summary>
 135    /// <param name="v1">The vector whose components are to be divided.</param>
 136    /// <param name="div">The scalar value by which to divide each component of the vector.</param>
 137    /// <returns>A new Vector2d whose components are the result of dividing the corresponding components of v1 by div.</
 138    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2304139    public static Vector2d operator /(Vector2d v1, Fixed64 div) => new(v1.X / div, v1.Y / div);
 140
 141    /// <summary>
 142    /// Determines whether two Vector2d instances are equal.
 143    /// </summary>
 144    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 824145    public static bool operator ==(Vector2d left, Vector2d right) => left.Equals(right);
 146
 147    /// <summary>
 148    /// Determines whether two Vector2d instances are not equal.
 149    /// </summary>
 150    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1609151    public static bool operator !=(Vector2d left, Vector2d right) => !left.Equals(right);
 152}

/home/runner/work/FixedMathSharp/FixedMathSharp/src/FixedMathSharp/Numerics/Vectors/Vector2d.Statics.cs

#LineLine coverage
 1//=======================================================================
 2// Vector2d.Statics.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 FixedMathSharp.Geometry;
 11
 12namespace FixedMathSharp;
 13
 14/// <content>
 15/// Static utility methods for <see cref="Vector2d"/>, including arithmetic helpers
 16/// and safe (non-saturating) operation variants.
 17/// </content>
 18public partial struct Vector2d
 19{
 20    /// <summary>
 21    /// Adds two vectors component-wise.
 22    /// </summary>
 23    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 124    public static Vector2d Add(Vector2d v1, Vector2d v2) => v1 + v2;
 25
 26    /// <summary>
 27    /// Attempts to add two vectors without component saturation.
 28    /// </summary>
 29    /// <param name="left">The left operand.</param>
 30    /// <param name="right">The right operand.</param>
 31    /// <param name="result">
 32    /// The exact component-wise sum when every component is representable; otherwise, <see langword="default"/>.
 33    /// </param>
 34    /// <returns>
 35    /// <see langword="true"/> when every exact component is representable; otherwise, <see langword="false"/>.
 36    /// </returns>
 37    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 38    public static bool TryAdd(Vector2d left, Vector2d right, out Vector2d result)
 39    {
 5940        if (!Fixed64.TryAdd(left.X, right.X, out Fixed64 x)
 5941            || !Fixed64.TryAdd(left.Y, right.Y, out Fixed64 y))
 42        {
 643            result = default;
 644            return false;
 45        }
 46
 5347        result = new Vector2d(x, y);
 5348        return true;
 49    }
 50
 51    /// <summary>
 52    /// Subtracts two vectors component-wise.
 53    /// </summary>
 54    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 155    public static Vector2d Subtract(Vector2d v1, Vector2d v2) => v1 - v2;
 56
 57    /// <summary>
 58    /// Attempts to subtract two vectors without component saturation.
 59    /// </summary>
 60    /// <param name="left">The left operand.</param>
 61    /// <param name="right">The right operand.</param>
 62    /// <param name="result">
 63    /// The exact component-wise difference when every component is representable; otherwise, <see langword="default"/>.
 64    /// </param>
 65    /// <returns>
 66    /// <see langword="true"/> when every exact component is representable; otherwise, <see langword="false"/>.
 67    /// </returns>
 68    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 69    public static bool TrySubtract(Vector2d left, Vector2d right, out Vector2d result)
 70    {
 2571        if (!Fixed64.TrySubtract(left.X, right.X, out Fixed64 x)
 2572            || !Fixed64.TrySubtract(left.Y, right.Y, out Fixed64 y))
 73        {
 374            result = default;
 375            return false;
 76        }
 77
 2278        result = new Vector2d(x, y);
 2279        return true;
 80    }
 81
 82    /// <summary>
 83    /// Attempts to add two vectors and subtract a third component-wise without intermediate saturation.
 84    /// </summary>
 85    /// <param name="firstAddend">The first addend.</param>
 86    /// <param name="secondAddend">The second addend.</param>
 87    /// <param name="subtrahend">The vector to subtract from the exact component-wise sum.</param>
 88    /// <param name="result">
 89    /// The exact component-wise result when every component is representable; otherwise, <see langword="default"/>.
 90    /// </param>
 91    /// <returns>
 92    /// <see langword="true"/> when every exact component is representable; otherwise, <see langword="false"/>.
 93    /// </returns>
 94    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 95    public static bool TryAddSubtract(
 96        Vector2d firstAddend,
 97        Vector2d secondAddend,
 98        Vector2d subtrahend,
 99        out Vector2d result)
 100    {
 3101        if (!Fixed64.TryAddSubtract(firstAddend.X, secondAddend.X, subtrahend.X, out Fixed64 x)
 3102            || !Fixed64.TryAddSubtract(firstAddend.Y, secondAddend.Y, subtrahend.Y, out Fixed64 y))
 103        {
 2104            result = default;
 2105            return false;
 106        }
 107
 1108        result = new Vector2d(x, y);
 1109        return true;
 110    }
 111
 112    /// <summary>
 113    /// Attempts to compute <c>(firstLeft + firstRight) -
 114    /// (secondLeft + secondRight)</c> component-wise without intermediate
 115    /// saturation.
 116    /// </summary>
 117    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 118    public static bool TrySubtractSums(
 119        Vector2d firstLeft,
 120        Vector2d firstRight,
 121        Vector2d secondLeft,
 122        Vector2d secondRight,
 123        out Vector2d result)
 124    {
 71125        bool representable = Fixed64.TrySubtractSums(
 71126                firstLeft.X,
 71127                firstRight.X,
 71128                secondLeft.X,
 71129                secondRight.X,
 71130                out Fixed64 x)
 71131            & Fixed64.TrySubtractSums(
 71132                firstLeft.Y,
 71133                firstRight.Y,
 71134                secondLeft.Y,
 71135                secondRight.Y,
 71136                out Fixed64 y);
 71137        if (!representable)
 138        {
 2139            result = default;
 2140            return false;
 141        }
 142
 69143        result = new Vector2d(x, y);
 69144        return true;
 145    }
 146
 147    /// <summary>
 148    /// Compares the exact component-difference projections of two vectors.
 149    /// </summary>
 150    /// <param name="candidate">The candidate point.</param>
 151    /// <param name="current">The point to compare against.</param>
 152    /// <param name="direction">The projection direction; it need not be normalized.</param>
 153    /// <returns>
 154    /// A negative value, zero, or a positive value when the candidate projection is
 155    /// respectively less than, equal to, or greater than the current projection.
 156    /// </returns>
 157    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 158    public static int CompareProjection(Vector2d candidate, Vector2d current, Vector2d direction) =>
 6159        WideGeometry.CompareDifferenceProjection(
 6160            candidate.X,
 6161            current.X,
 6162            direction.X,
 6163            candidate.Y,
 6164            current.Y,
 6165            direction.Y,
 6166            Fixed64.Zero,
 6167            Fixed64.Zero,
 6168            Fixed64.Zero);
 169
 170    /// <summary>
 171    /// Multiplies two vectors component-wise.
 172    /// </summary>
 173    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2174    public static Vector2d Multiply(Vector2d v1, Vector2d v2) => v1 * v2;
 175
 176    /// <summary>
 177    /// Multiplies each vector component by the specified scalar.
 178    /// </summary>
 179    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1180    public static Vector2d Multiply(Vector2d value, Fixed64 factor) => value * factor;
 181
 182    /// <summary>
 183    /// Divides each component of the first vector by the corresponding component of the second vector.
 184    /// </summary>
 185    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1186    public static Vector2d Divide(Vector2d v1, Vector2d v2) => new(v1.X / v2.X, v1.Y / v2.Y);
 187
 188    /// <summary>
 189    /// Divides each vector component by the specified scalar.
 190    /// </summary>
 191    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1192    public static Vector2d Divide(Vector2d value, Fixed64 divisor) => value / divisor;
 193
 194    /// <summary>
 195    /// Clamps each component of the given vector within the specified min and max bounds.
 196    /// </summary>
 197    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 198    public static Vector2d Clamp(Vector2d value, Vector2d min, Vector2d max) =>
 4199        new(FixedMath.Clamp(value.X, min.X, max.X),
 4200            FixedMath.Clamp(value.Y, min.Y, max.Y));
 201
 202    /// <summary>
 203    /// Normalizes the given vector, returning a unit vector with the same direction.
 204    /// </summary>
 205    /// <param name="value">The vector to normalize.</param>
 206    /// <returns>A normalized (unit) vector with the same direction.</returns>
 207    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 208    public static Vector2d GetNormalized(Vector2d value)
 209    {
 86210        bool magnitudeIsRepresentable = TryGetMagnitude(
 86211            value,
 86212            out Fixed64 mag,
 86213            out bool isNormalized);
 214
 86215        if (mag == Fixed64.Zero)
 1216            return new Vector2d(Fixed64.Zero, Fixed64.Zero);
 217
 85218        if (isNormalized)
 26219            return value;
 220
 59221        if (!magnitudeIsRepresentable || mag == Fixed64.One)
 3222            return WideNormalization.GetNormalized(value);
 223
 56224        if (mag <= FixedMath.ScaleSafeMagnitudeThreshold)
 10225            return GetScaleNormalized(value);
 226
 46227        var normalized = new Vector2d(
 46228            FixedMath.FastDiv(value.X, mag),
 46229            FixedMath.FastDiv(value.Y, mag));
 46230        return normalized.IsNormalized()
 46231            ? normalized
 46232            : WideNormalization.GetNormalized(value);
 233    }
 234
 235    internal static Vector2d GetScaleNormalized(Vector2d value)
 236    {
 1148237        Fixed64 scale = FixedMath.Max(value.X.Abs(), value.Y.Abs());
 1148238        Vector2d scaled = value / scale;
 1148239        Fixed64 scaledMagnitude = FixedMath.GetScaledMagnitude(
 1148240            scaled.X,
 1148241            scaled.Y,
 1148242            Fixed64.Zero,
 1148243            Fixed64.Zero);
 1148244        return scaled / scaledMagnitude;
 245    }
 246
 247    /// <summary>
 248    /// Attempts to transform a component-scaled local point by a rotation and
 249    /// world origin with one final round-half-to-even conversion per
 250    /// component.
 251    /// </summary>
 252    public static bool TryTransformScaledPoint(
 253        Vector2d origin,
 254        Vector2d localPoint,
 255        Vector2d scale,
 256        Fixed64 angleInRadians,
 257        out Vector2d result) =>
 3258        TryTransformScaledPoint(
 3259            origin,
 3260            localPoint,
 3261            scale,
 3262            Vector2d.Zero,
 3263            angleInRadians,
 3264            out result);
 265
 266    /// <summary>
 267    /// Attempts to transform a component-scaled local point plus an unscaled
 268    /// local displacement by a rotation and world origin with one final
 269    /// round-half-to-even conversion per component.
 270    /// </summary>
 271    /// <remarks>
 272    /// Computes
 273    /// <c>origin + Rotate(scale * localPoint + localDisplacement)</c> without
 274    /// narrowing the scaled point, local sum, or rotated offset independently.
 275    /// </remarks>
 276    public static bool TryTransformScaledPoint(
 277        Vector2d origin,
 278        Vector2d localPoint,
 279        Vector2d scale,
 280        Vector2d localDisplacement,
 281        Fixed64 angleInRadians,
 282        out Vector2d result) =>
 69283        WideVector2dTransform.TryTransformScaledPoint(
 69284            origin,
 69285            localPoint,
 69286            scale,
 69287            localDisplacement,
 69288            angleInRadians,
 69289            out result);
 290
 291    /// <summary>
 292    /// Attempts to transform a world point into a component-scaled local frame
 293    /// with one final round-half-to-even conversion per component.
 294    /// </summary>
 295    /// <remarks>
 296    /// Computes <c>InverseRotate(worldPoint - origin) / scale</c> without
 297    /// narrowing the world offset, rotated projection, or scale division
 298    /// independently. A zero scale component or unrepresentable final
 299    /// coordinate returns false and a zero result.
 300    /// </remarks>
 301    public static bool TryInverseTransformScaledPoint(
 302        Vector2d origin,
 303        Vector2d worldPoint,
 304        Vector2d scale,
 305        Fixed64 angleInRadians,
 306        out Vector2d localPoint) =>
 71307        WideVector2dTransform.TryInverseTransformScaledPoint(
 71308            origin,
 71309            worldPoint,
 71310            scale,
 71311            angleInRadians,
 71312            out localPoint);
 313
 314    /// <summary>
 315    /// Attempts to compose two component-scaled offsets in a shared frame and
 316    /// one rotated inner-frame displacement with one final round-half-to-even
 317    /// conversion per component.
 318    /// </summary>
 319    /// <remarks>
 320    /// Computes
 321    /// <c>outerScale * outerLocalPoint
 322    /// + innerFrameScale * innerFrameOffset
 323    /// + Rotate(innerLocalDisplacement)</c>
 324    /// without narrowing either scaled offset or the rotated displacement
 325    /// independently.
 326    /// </remarks>
 327    public static bool TryComposeScaledLocalPoints(
 328        Vector2d outerLocalPoint,
 329        Vector2d outerScale,
 330        Vector2d innerFrameOffset,
 331        Vector2d innerFrameScale,
 332        Vector2d innerLocalDisplacement,
 333        Fixed64 innerAngleInRadians,
 334        out Vector2d result) =>
 68335        WideVector2dTransform.TryComposeScaledLocalPoints(
 68336            outerLocalPoint,
 68337            outerScale,
 68338            innerFrameOffset,
 68339            innerFrameScale,
 68340            innerLocalDisplacement,
 68341            innerAngleInRadians,
 68342            out result);
 343
 344    /// <summary>
 345    /// Returns the normalized direction from <paramref name="start"/> toward
 346    /// <paramref name="end"/> across the complete coordinate domain.
 347    /// </summary>
 348    /// <remarks>
 349    /// Equal endpoints return <see cref="Zero"/>. Endpoint differences are
 350    /// evaluated exactly even when a component cannot be represented by
 351    /// <see cref="Fixed64"/>.
 352    /// </remarks>
 353    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 354    public static Vector2d GetDirection(Vector2d start, Vector2d end) =>
 4355        WideNormalization.GetDirection(start, end);
 356
 357    /// <summary>
 358    /// Returns the magnitude (length) of the given vector.
 359    /// </summary>
 360    /// <param name="vector">The vector to compute the magnitude of.</param>
 361    /// <returns>The magnitude (length) of the vector.</returns>
 362    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 363    public static Fixed64 GetMagnitude(Vector2d vector)
 364    {
 48365        _ = TryGetMagnitude(vector, out Fixed64 magnitude);
 48366        return magnitude;
 367    }
 368
 369    /// <summary>
 370    /// Attempts to return the magnitude of the given vector without saturating the result.
 371    /// </summary>
 372    /// <param name="vector">The vector to measure.</param>
 373    /// <param name="magnitude">The magnitude, or <see cref="Fixed64.MaxValue"/> when it is not representable.</param>
 374    /// <returns><see langword="true"/> when the magnitude fits in <see cref="Fixed64"/>; otherwise, <see langword="fals
 375    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 376    public static bool TryGetMagnitude(Vector2d vector, out Fixed64 magnitude) =>
 59377        TryGetMagnitude(vector, out magnitude, out _);
 378
 379    private static bool TryGetMagnitude(
 380        Vector2d vector,
 381        out Fixed64 magnitude,
 382        out bool isNormalized)
 383    {
 161384        Fixed64 mag = (vector.X * vector.X) + (vector.Y * vector.Y);
 161385        isNormalized = mag != Fixed64.Zero
 161386            && FixedMath.Abs(mag - Fixed64.One) <= Fixed64.Epsilon;
 387
 161388        if (mag == Fixed64.MaxValue)
 13389            return FixedMath.TryGetScaledMagnitude(
 13390                vector.X,
 13391                vector.Y,
 13392                Fixed64.Zero,
 13393                Fixed64.Zero,
 13394                out magnitude);
 395
 148396        if (mag <= FixedMath.ScaleSafeMagnitudeSquaredThreshold)
 397        {
 23398            magnitude = FixedMath.GetScaledMagnitude(
 23399                vector.X,
 23400                vector.Y,
 23401                Fixed64.Zero,
 23402                Fixed64.Zero);
 23403            return true;
 404        }
 405
 125406        if (isNormalized)
 407        {
 35408            magnitude = Fixed64.One;
 35409            return true;
 410        }
 411
 90412        magnitude = FixedMath.Sqrt(mag);
 90413        return true;
 414    }
 415
 416    /// <summary>
 417    /// Attempts to return the distance between two endpoints without saturating
 418    /// either component difference.
 419    /// </summary>
 420    /// <param name="start">The first endpoint.</param>
 421    /// <param name="end">The second endpoint.</param>
 422    /// <param name="distance">The rounded distance, or <see cref="Fixed64.MaxValue"/> when it is not representable.</pa
 423    /// <returns><see langword="true"/> when the distance fits in <see cref="Fixed64"/>; otherwise, <see langword="false
 424    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 425    public static bool TryGetDistance(Vector2d start, Vector2d end, out Fixed64 distance) =>
 4426        WideGeometry.TryGetDistance(start, end, out distance);
 427
 428    /// <summary>
 429    /// Compares the exact squared magnitudes of two vectors without fixed-point saturation.
 430    /// </summary>
 431    /// <returns>A negative value when <paramref name="left"/> is shorter, zero when the
 432    /// magnitudes are equal, or a positive value when <paramref name="left"/> is longer.</returns>
 433    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 434    public static int CompareMagnitudeSquared(Vector2d left, Vector2d right) =>
 5435        Fixed64.CompareMagnitudeSquared(
 5436            left.X,
 5437            left.Y,
 5438            Fixed64.Zero,
 5439            Fixed64.Zero,
 5440            right.X,
 5441            right.Y,
 5442            Fixed64.Zero,
 5443            Fixed64.Zero);
 444
 445    /// <summary>
 446    /// Returns a new <see cref="Vector2d"/> where each component is the absolute value of the corresponding input compo
 447    /// </summary>
 448    /// <param name="value">The input vector.</param>
 449    /// <returns>A vector with absolute values for each component.</returns>
 450    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1451    public static Vector2d Abs(Vector2d value) => new(value.X.Abs(), value.Y.Abs());
 452
 453    /// <summary>
 454    /// Returns a new <see cref="Vector2d"/> where each component is the sign of the corresponding input component.
 455    /// </summary>
 456    /// <param name="value">The input vector.</param>
 457    /// <returns>A vector where each component is -1, 0, or 1 based on the sign of the input.</returns>
 458    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1459    public static Vector2d Sign(Vector2d value) => new(value.X.Sign(), value.Y.Sign());
 460
 461    /// <summary>
 462    /// Attempts to calculate the exact non-negative weighted average with one
 463    /// final round-half-to-even conversion per component.
 464    /// </summary>
 465    /// <remarks>
 466    /// Zero-weight values are ignored. The operation returns
 467    /// <see langword="false"/> only when the total weight is zero.
 468    /// </remarks>
 469    public static bool TryGetWeightedAverage(
 470        ReadOnlySpan<Vector2d> values,
 471        ReadOnlySpan<Fixed64> weights,
 472        out Vector2d average)
 473    {
 5474        WideWeightedAverage.ValidateInputs(values.Length, weights);
 3475        return WideWeightedAverage.TryGet(values, weights, out average);
 476    }
 477
 478    /// <summary>
 479    /// Calculates the arithmetic mean with one final round-half-to-even
 480    /// conversion per component.
 481    /// </summary>
 482    /// <param name="values">The non-empty sequence of vectors to average.</param>
 483    /// <returns>The arithmetic mean of <paramref name="values"/>.</returns>
 484    /// <exception cref="ArgumentException">
 485    /// <paramref name="values"/> is empty.
 486    /// </exception>
 487    public static Vector2d GetAverage(ReadOnlySpan<Vector2d> values)
 488    {
 103489        if (values.IsEmpty)
 490        {
 1491            throw new ArgumentException(
 1492                "At least one value is required.",
 1493                nameof(values));
 494        }
 495
 102496        return WideWeightedAverage.GetAverage(values);
 497    }
 498
 499    /// <summary>
 500    /// Creates a vector from a given angle in radians.
 501    /// </summary>
 1502    public static Vector2d CreateRotation(Fixed64 angle) => new(FixedMath.Cos(angle), FixedMath.Sin(angle));
 503
 504    /// <summary>
 505    /// Linearly interpolates between two vectors.
 506    /// </summary>
 507    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 508    public static Vector2d Lerp(Vector2d a, Vector2d b, Fixed64 amount)
 509    {
 3510        amount = FixedMath.Clamp01(amount);
 3511        return new Vector2d(
 3512            FixedMath.Lerp(a.X, b.X, amount),
 3513            FixedMath.Lerp(a.Y, b.Y, amount));
 514    }
 515
 516    /// <summary>
 517    /// Calculates a position between three points using barycentric weights for the second and third vertices.
 518    /// </summary>
 519    /// <param name="coordA">The first vertex of the triangle.</param>
 520    /// <param name="coordB">The second vertex of the triangle.</param>
 521    /// <param name="coordC">The third vertex of the triangle.</param>
 522    /// <param name="weightB">The barycentric weight for the second vertex.</param>
 523    /// <param name="weightC">The barycentric weight for the third vertex.</param>
 524    /// <returns>The cartesian translation represented by the barycentric coordinates within the triangle.</returns>
 525    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 526    public static Vector2d BarycentricCoordinates(
 527        Vector2d coordA,
 528        Vector2d coordB,
 529        Vector2d coordC,
 530        Fixed64 weightB,
 531        Fixed64 weightC)
 532    {
 10533        return new(
 10534            FixedMath.BarycentricCoordinate(coordA.X, coordB.X, coordC.X, weightB, weightC),
 10535            FixedMath.BarycentricCoordinate(coordA.Y, coordB.Y, coordC.Y, weightB, weightC));
 536    }
 537
 538    /// <summary>
 539    /// Computes the distance between two vectors using the Euclidean distance formula.
 540    /// </summary>
 541    /// <param name="start">The starting vector.</param>
 542    /// <param name="end">The ending vector.</param>
 543    /// <returns>The Euclidean distance between the two vectors.</returns>
 544    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 4545    public static Fixed64 Distance(Vector2d start, Vector2d end) => start.Distance(end);
 546
 547    /// <summary>
 548    /// Calculates the squared distance between two vectors, avoiding the need for a square root operation.
 549    /// </summary>
 550    /// <returns>The squared distance between the two vectors.</returns>
 551    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 47552    public static Fixed64 DistanceSquared(Vector2d start, Vector2d end) => start.DistanceSquared(end);
 553
 554    /// <summary>
 555    /// Calculates the closest point on a finite line segment to a given point.
 556    /// </summary>
 557    /// <param name="point">The point to project onto the segment.</param>
 558    /// <param name="start">The start of the line segment.</param>
 559    /// <param name="end">The end of the line segment.</param>
 560    /// <returns>The closest point on the segment to the given point.</returns>
 561    /// <remarks>
 562    /// Zero-length segments deterministically return <paramref name="start"/>.
 563    /// </remarks>
 564    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 565    public static Vector2d ClosestPointOnLineSegment(Vector2d point, Vector2d start, Vector2d end)
 566    {
 110567        Fixed64 t = GetClosestPointOnLineSegmentParameter(point, start, end);
 110568        return new Vector2d(
 110569            FixedMath.Lerp(start.X, end.X, t),
 110570            FixedMath.Lerp(start.Y, end.Y, t));
 571    }
 572
 573    internal static Fixed64 GetClosestPointOnLineSegmentParameter(
 574        Vector2d point,
 575        Vector2d start,
 576        Vector2d end)
 577    {
 114578        Signed192 denominator = WideGeometry.GetDifferenceDotProduct2D(
 114579            end.X, start.X, end.Y, start.Y,
 114580            end.X, start.X, end.Y, start.Y);
 114581        if (denominator.IsZero)
 25582            return Fixed64.Zero;
 583
 89584        Signed192 numerator = WideGeometry.GetDifferenceDotProduct2D(
 89585            point.X, start.X, point.Y, start.Y,
 89586            end.X, start.X, end.Y, start.Y);
 89587        if (numerator.Sign <= 0)
 21588            return Fixed64.Zero;
 68589        if (WideArithmetic.CompareMagnitude(numerator, denominator) >= 0)
 31590            return Fixed64.One;
 591
 37592        _ = Fixed64.TryGetUnitIntervalRatio(numerator, denominator, out Fixed64 parameter);
 37593        return parameter;
 594    }
 595
 596    /// <summary>
 597    /// Compares the exact squared distances between two pairs of points without fixed-point saturation.
 598    /// </summary>
 599    /// <returns>A negative value when the left distance is shorter, zero when the
 600    /// distances are equal, or a positive value when the left distance is longer.</returns>
 601    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 602    public static int CompareDistanceSquared(
 603        Vector2d leftStart,
 604        Vector2d leftEnd,
 605        Vector2d rightStart,
 606        Vector2d rightEnd)
 607    {
 45608        Signed192 leftDistance = WideGeometry.GetDifferenceDotProduct2D(
 45609            leftStart.X, leftEnd.X, leftStart.Y, leftEnd.Y,
 45610            leftStart.X, leftEnd.X, leftStart.Y, leftEnd.Y);
 45611        Signed192 rightDistance = WideGeometry.GetDifferenceDotProduct2D(
 45612            rightStart.X, rightEnd.X, rightStart.Y, rightEnd.Y,
 45613            rightStart.X, rightEnd.X, rightStart.Y, rightEnd.Y);
 614
 45615        return WideArithmetic.CompareMagnitude(leftDistance, rightDistance);
 616    }
 617
 618    /// <summary>
 619    /// Returns the exact orientation sign of the ordered points without fixed-point saturation.
 620    /// </summary>
 621    /// <returns><c>1</c> for a counter-clockwise turn, <c>-1</c> for a clockwise
 622    /// turn, or <c>0</c> when the points are exactly collinear.</returns>
 623    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 624    public static int OrientationSign(Vector2d origin, Vector2d first, Vector2d second) =>
 3625        WideGeometry.GetDifferenceCrossProduct2D(
 3626            first.X, origin.X, first.Y, origin.Y,
 3627            second.X, origin.X, second.Y, origin.Y).Sign;
 628
 629    /// <summary>
 630    /// Calculates the forward direction vector in 2D based on a yaw (angle).
 631    /// </summary>
 632    /// <remarks>
 633    /// This is a polar-angle helper: angle zero points along <see cref="Vector2d.Right"/>.
 634    /// It intentionally differs from the named <see cref="Vector2d.Forward"/> plane constant,
 635    /// which is <c>+Y</c>.
 636    /// </remarks>
 637    /// <param name="angle">The angle in radians representing the rotation in 2D space.</param>
 638    /// <returns>A unit vector representing the forward direction.</returns>
 639    public static Vector2d ForwardDirection(Fixed64 angle)
 640    {
 3641        Fixed64 x = FixedMath.Cos(angle); // Forward in the x-direction
 3642        Fixed64 y = FixedMath.Sin(angle); // Forward in the y-direction
 3643        return new Vector2d(x, y);
 644    }
 645
 646    /// <summary>
 647    /// Dot Product of two vectors.
 648    /// </summary>
 649    /// <param name="lhs"></param>
 650    /// <param name="rhs"></param>
 651    /// <returns></returns>
 652    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 217653    public static Fixed64 Dot(Vector2d lhs, Vector2d rhs) => lhs.Dot(rhs.X, rhs.Y);
 654
 655    /// <summary>
 656    /// Cross Product of two vectors.
 657    /// </summary>
 658    /// <param name="lhs"></param>
 659    /// <param name="rhs"></param>
 660    /// <returns></returns>
 661    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1662    public static Fixed64 CrossProduct(Vector2d lhs, Vector2d rhs) => lhs.CrossProduct(rhs);
 663
 664    /// <summary>
 665    /// Rotates this vector by the specified angle (in radians).
 666    /// </summary>
 667    /// <param name="vec">The vector to rotate.</param>
 668    /// <param name="angleInRadians">The angle in radians.</param>
 669    /// <returns>The rotated vector.</returns>
 670    public static Vector2d Rotate(Vector2d vec, Fixed64 angleInRadians)
 671    {
 16672        Fixed64 cos = FixedMath.Cos(angleInRadians);
 16673        Fixed64 sin = FixedMath.Sin(angleInRadians);
 16674        return new Vector2d(
 16675            vec.X * cos - vec.Y * sin,
 16676            vec.X * sin + vec.Y * cos
 16677        );
 678    }
 679
 680    /// <summary>
 681    /// Attempts to rotate a vector by the specified angle with one final
 682    /// round-half-to-even conversion per component.
 683    /// </summary>
 684    /// <returns>
 685    /// <see langword="true"/> when both final components are representable;
 686    /// otherwise, <see langword="false"/> and <paramref name="result"/> is
 687    /// <see langword="default"/>.
 688    /// </returns>
 689    public static bool TryRotate(
 690        Vector2d vector,
 691        Fixed64 angleInRadians,
 692        out Vector2d result)
 693    {
 178694        Fixed64 cosine = FixedMath.Cos(angleInRadians);
 178695        Fixed64 sine = FixedMath.Sin(angleInRadians);
 178696        bool representable = Fixed64.TrySubtractProducts(
 178697                vector.X,
 178698                cosine,
 178699                vector.Y,
 178700                sine,
 178701                out Fixed64 x)
 178702            & Fixed64.TryAddProducts(
 178703                vector.X,
 178704                sine,
 178705                vector.Y,
 178706                cosine,
 178707                out Fixed64 y);
 178708        if (!representable)
 709        {
 2710            result = default;
 2711            return false;
 712        }
 713
 176714        result = new Vector2d(x, y);
 176715        return true;
 716    }
 717
 718    /// <summary>
 719    /// Attempts to transform a local point by a rotation and origin with one
 720    /// final round-half-to-even conversion per component.
 721    /// </summary>
 722    /// <returns>
 723    /// <see langword="true"/> when both final world components are
 724    /// representable; otherwise, <see langword="false"/> and
 725    /// <paramref name="result"/> is <see langword="default"/>.
 726    /// </returns>
 727    public static bool TryTransformPoint(
 728        Vector2d origin,
 729        Vector2d localPoint,
 730        Fixed64 angleInRadians,
 731        out Vector2d result)
 732    {
 70733        if (angleInRadians == Fixed64.Zero)
 35734            return TryAdd(origin, localPoint, out result);
 735
 35736        return WideVector2dTransform.TryTransformPoint(
 35737            origin,
 35738            localPoint,
 35739            angleInRadians,
 35740            out result);
 741    }
 742
 743    /// <summary>
 744    /// Attempts to transform a local point by a rotation and add two origins
 745    /// with one final round-half-to-even conversion per component.
 746    /// </summary>
 747    /// <returns>
 748    /// <see langword="true"/> when both final world components are
 749    /// representable; otherwise, <see langword="false"/> and
 750    /// <paramref name="result"/> is <see langword="default"/>.
 751    /// </returns>
 752    public static bool TryTransformPoint(
 753        Vector2d firstOrigin,
 754        Vector2d secondOrigin,
 755        Vector2d localPoint,
 756        Fixed64 angleInRadians,
 757        out Vector2d result) =>
 69758        WideVector2dTransform.TryTransformPoint(
 69759            firstOrigin,
 69760            secondOrigin,
 69761            localPoint,
 69762            angleInRadians,
 69763            out result);
 764
 765    /// <summary>
 766    /// Attempts to obtain the exact relative offset
 767    /// <c>firstOrigin + firstOffset - secondOrigin - Rotate(secondLocalPoint)</c>.
 768    /// </summary>
 769    /// <remarks>
 770    /// No rotated point or intermediate sum is narrowed independently.
 771    /// </remarks>
 772    /// <returns>
 773    /// <see langword="true"/> when both final components are representable;
 774    /// otherwise, <see langword="false"/> and <paramref name="result"/> is
 775    /// <see langword="default"/>.
 776    /// </returns>
 777    public static bool TryGetRelativeOffset(
 778        Vector2d firstOrigin,
 779        Vector2d firstOffset,
 780        Vector2d secondOrigin,
 781        Vector2d secondLocalPoint,
 782        Fixed64 angleInRadians,
 783        out Vector2d result)
 784    {
 70785        if (angleInRadians == Fixed64.Zero)
 786        {
 35787            return TrySubtractSums(
 35788                firstOrigin,
 35789                firstOffset,
 35790                secondOrigin,
 35791                secondLocalPoint,
 35792                out result);
 793        }
 794
 35795        return WideVector2dTransform.TryGetRelativeOffset(
 35796            firstOrigin,
 35797            firstOffset,
 35798            secondOrigin,
 35799            secondLocalPoint,
 35800            angleInRadians,
 35801            out result);
 802    }
 803
 804    /// <summary>
 805    /// Attempts to obtain the exact relative offset between two transformed
 806    /// local points.
 807    /// </summary>
 808    /// <remarks>
 809    /// The computed relation is
 810    /// <c>firstOrigin + Rotate(firstLocalPoint, firstAngleInRadians)
 811    /// - secondOrigin - Rotate(secondLocalPoint, secondAngleInRadians)</c>.
 812    /// Neither rotated point nor any intermediate sum is narrowed
 813    /// independently.
 814    /// </remarks>
 815    /// <returns>
 816    /// <see langword="true"/> when both final components are representable;
 817    /// otherwise, <see langword="false"/> and <paramref name="result"/> is
 818    /// <see langword="default"/>.
 819    /// </returns>
 820    public static bool TryGetRelativeOffset(
 821        Vector2d firstOrigin,
 822        Vector2d firstLocalPoint,
 823        Fixed64 firstAngleInRadians,
 824        Vector2d secondOrigin,
 825        Vector2d secondLocalPoint,
 826        Fixed64 secondAngleInRadians,
 827        out Vector2d result)
 828    {
 69829        if (firstAngleInRadians == Fixed64.Zero
 69830            && secondAngleInRadians == Fixed64.Zero)
 831        {
 34832            return TrySubtractSums(
 34833                firstOrigin,
 34834                firstLocalPoint,
 34835                secondOrigin,
 34836                secondLocalPoint,
 34837                out result);
 838        }
 839
 35840        return WideVector2dTransform.TryGetRelativeOffset(
 35841            firstOrigin,
 35842            firstLocalPoint,
 35843            firstAngleInRadians,
 35844            secondOrigin,
 35845            secondLocalPoint,
 35846            secondAngleInRadians,
 35847            out result);
 848    }
 849}

Methods/Properties

ToString()
ToString(System.String,System.IFormatProvider)
TryFormat(System.Span`1<System.Char>,System.Int32&,System.ReadOnlySpan`1<System.Char>,System.IFormatProvider)
ToVector3d(FixedMathSharp.Fixed64)
ToVector4d(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Deconstruct(FixedMathSharp.Fixed64&,FixedMathSharp.Fixed64&)
Deconstruct(System.Int32&,System.Int32&)
Deconstruct(System.Int64&,System.Int64&)
Deconstruct(System.Double&,System.Double&)
ToDegrees(FixedMathSharp.Vector2d)
ToRadians(FixedMathSharp.Vector2d)
get_Forward()
get_Backward()
get_Right()
get_Left()
get_One()
get_Negative()
get_Zero()
.ctor(System.Int32,System.Int32)
.ctor(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
FromDouble(System.Double,System.Double)
get_RotatedRight()
get_RotatedLeft()
get_RightHandNormal()
get_LeftHandNormal()
get_Normalized()
get_Magnitude()
get_MagnitudeSquared()
get_LongStateHash()
get_StateHash()
get_Item(System.Int32)
set_Item(System.Int32,FixedMathSharp.Fixed64)
Set(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
AddInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
AddInPlace(FixedMathSharp.Fixed64)
AddInPlace(FixedMathSharp.Vector2d)
SubtractInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
SubtractInPlace(FixedMathSharp.Fixed64)
SubtractInPlace(FixedMathSharp.Vector2d)
MultiplyInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
MultiplyInPlace(FixedMathSharp.Fixed64)
MultiplyInPlace(FixedMathSharp.Vector2d)
DivideInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
DivideInPlace(FixedMathSharp.Fixed64)
DivideInPlace(FixedMathSharp.Vector2d)
NormalizeInPlace()
NormalizeInPlace(FixedMathSharp.Fixed64&)
IsNormalized()
TryGetMagnitudeCeiling(FixedMathSharp.Fixed64&)
LerpInPlace(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
LerpInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Lerp(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
RotateInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Rotated(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Rotated(FixedMathSharp.Vector2d)
RotateInverse(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
RotateRightInPlace()
RotateLeftInPlace()
ReflectInPlace(FixedMathSharp.Vector2d)
ReflectInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
ReflectInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Reflected(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Reflected(FixedMathSharp.Vector2d)
Dot(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Dot(FixedMathSharp.Vector2d)
CrossProduct(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
CrossProduct(FixedMathSharp.Vector2d)
Distance(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Distance(FixedMathSharp.Vector2d)
DistanceSquared(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
DistanceSquared(FixedMathSharp.Vector2d)
EqualsZero()
NotZero()
AllComponentsGreaterThanEpsilon()
Equals(System.Object)
Equals(FixedMathSharp.Vector2d)
Equals(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
GetHashCode()
GetHashCode(FixedMathSharp.Vector2d)
CompareTo(FixedMathSharp.Vector2d)
op_Addition(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
op_Addition(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
op_Addition(FixedMathSharp.Fixed64,FixedMathSharp.Vector2d)
op_Addition(FixedMathSharp.Vector2d,System.ValueTuple`2<System.Int32,System.Int32>)
op_Addition(System.ValueTuple`2<System.Int32,System.Int32>,FixedMathSharp.Vector2d)
op_Subtraction(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
op_Subtraction(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
op_Subtraction(FixedMathSharp.Fixed64,FixedMathSharp.Vector2d)
op_Subtraction(FixedMathSharp.Vector2d,System.ValueTuple`2<System.Int32,System.Int32>)
op_Subtraction(System.ValueTuple`2<System.Int32,System.Int32>,FixedMathSharp.Vector2d)
op_UnaryNegation(FixedMathSharp.Vector2d)
op_Multiply(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
op_Multiply(FixedMathSharp.Fixed64,FixedMathSharp.Vector2d)
op_Multiply(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
op_Division(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
op_Equality(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
op_Inequality(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
Add(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
TryAdd(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d&)
Subtract(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
TrySubtract(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d&)
TryAddSubtract(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d&)
TrySubtractSums(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d&)
CompareProjection(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
Multiply(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
Multiply(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
Divide(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
Divide(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
Clamp(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
GetNormalized(FixedMathSharp.Vector2d)
GetScaleNormalized(FixedMathSharp.Vector2d)
TryTransformScaledPoint(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d&)
TryTransformScaledPoint(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d&)
TryInverseTransformScaledPoint(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d&)
TryComposeScaledLocalPoints(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d&)
GetDirection(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
GetMagnitude(FixedMathSharp.Vector2d)
TryGetMagnitude(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64&)
TryGetMagnitude(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64&,System.Boolean&)
TryGetDistance(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64&)
CompareMagnitudeSquared(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
Abs(FixedMathSharp.Vector2d)
Sign(FixedMathSharp.Vector2d)
TryGetWeightedAverage(System.ReadOnlySpan`1<FixedMathSharp.Vector2d>,System.ReadOnlySpan`1<FixedMathSharp.Fixed64>,FixedMathSharp.Vector2d&)
GetAverage(System.ReadOnlySpan`1<FixedMathSharp.Vector2d>)
CreateRotation(FixedMathSharp.Fixed64)
Lerp(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
BarycentricCoordinates(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Distance(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
DistanceSquared(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
ClosestPointOnLineSegment(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
GetClosestPointOnLineSegmentParameter(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
CompareDistanceSquared(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
OrientationSign(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
ForwardDirection(FixedMathSharp.Fixed64)
Dot(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
CrossProduct(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
Rotate(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
TryRotate(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d&)
TryTransformPoint(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d&)
TryTransformPoint(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d&)
TryGetRelativeOffset(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d&)
TryGetRelativeOffset(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d&)