< Summary

Line coverage
100%
Covered lines: 634
Uncovered lines: 0
Coverable lines: 634
Total lines: 2343
Line coverage: 100%
Branch coverage
100%
Covered branches: 160
Total branches: 160
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%1414100%
File 1: ToVector2d()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_Up()100%11100%
File 2: get_Right()100%11100%
File 2: get_Down()100%11100%
File 2: get_Left()100%11100%
File 2: get_Forward()100%11100%
File 2: get_Backward()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_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_Direction()100%11100%
File 2: get_IsZero()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%66100%
File 2: DivideInPlace(...)100%22100%
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: AllComponentsGreaterThanEpsilon()100%44100%
File 2: SnapSmallComponentsToZero(...)100%88100%
File 2: Distance(...)100%22100%
File 2: DistanceSquared(...)100%11100%
File 2: Dot(...)100%11100%
File 2: CrossProduct(...)100%11100%
File 2: Cross(...)100%11100%
File 3: Equals(...)100%22100%
File 3: Equals(...)100%44100%
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_UnaryNegation(...)100%11100%
File 4: op_Multiply(...)100%11100%
File 4: op_Multiply(...)100%11100%
File 4: op_Multiply(...)100%11100%
File 4: op_Multiply(...)100%11100%
File 4: op_Multiply(...)100%11100%
File 4: op_Multiply(...)100%11100%
File 4: op_Multiply(...)100%44100%
File 4: op_Multiply(...)100%11100%
File 4: op_Multiply(...)100%11100%
File 4: op_Division(...)100%22100%
File 4: op_Division(...)100%66100%
File 4: op_Division(...)100%22100%
File 4: op_Multiply(...)100%11100%
File 4: op_Multiply(...)100%11100%
File 4: op_Equality(...)100%11100%
File 4: op_Inequality(...)100%11100%
File 4: op_GreaterThan(...)100%44100%
File 4: op_LessThan(...)100%44100%
File 4: op_GreaterThanOrEqual(...)100%44100%
File 4: op_LessThanOrEqual(...)100%44100%
File 5: Add(...)100%11100%
File 5: TryAdd(...)100%66100%
File 5: Subtract(...)100%11100%
File 5: TrySubtract(...)100%66100%
File 5: TryAddSubtract(...)100%66100%
File 5: TrySubtractSums(...)100%22100%
File 5: TryCross(...)100%22100%
File 5: TryDot(...)100%11100%
File 5: TryLinearCombination(...)100%22100%
File 5: TryLinearCombination(...)100%22100%
File 5: TryScaledLinearCombination(...)100%22100%
File 5: CompareProjection(...)100%11100%
File 5: ProjectNonNegativeDifference(...)100%11100%
File 5: ProjectNonNegativeDifferenceParameter(...)100%11100%
File 5: Multiply(...)100%11100%
File 5: Multiply(...)100%11100%
File 5: Divide(...)100%11100%
File 5: Divide(...)100%11100%
File 5: Lerp(...)100%11100%
File 5: UnclampedLerp(...)100%11100%
File 5: SpeedLerp(...)100%22100%
File 5: Slerp(...)100%11100%
File 5: CatmullRom(...)100%11100%
File 5: HermiteSpline(...)100%11100%
File 5: SmoothStep(...)100%11100%
File 5: GetNormalized(...)100%1212100%
File 5: GetScaleNormalized(...)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: CompareDistanceSquared(...)100%11100%
File 5: ScalarTripleProductSign(...)100%11100%
File 5: Abs(...)100%11100%
File 5: Sign(...)100%11100%
File 5: TryGetWeightedAverage(...)100%11100%
File 5: Clamp(...)100%11100%
File 5: ClampMagnitude(...)100%22100%
File 5: AreParallel(...)100%11100%
File 5: AreAlmostParallel(...)100%11100%
File 5: Midpoint(...)100%11100%
File 5: Distance(...)100%11100%
File 5: DistanceSquared(...)100%11100%
File 5: ClosestPointOnLineSegment(...)100%66100%
File 5: Dot(...)100%11100%
File 5: Cross(...)100%11100%
File 5: CrossProduct(...)100%11100%
File 5: Project(...)100%22100%
File 5: ProjectOnPlane(...)100%22100%
File 5: GetNormalizedProjectionOnPlane(...)100%11100%
File 5: ProjectOnPlane(...)100%22100%
File 5: Angle(...)100%22100%
File 5: BarycentricCoordinates(...)100%11100%
File 5: Max(...)100%11100%
File 5: Min(...)100%11100%
File 5: Negate(...)100%11100%
File 5: Rotate(...)100%11100%
File 5: InverseRotate(...)100%11100%
File 5: Reflect(...)100%11100%
File 5: Transform(...)100%11100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// Vector3d.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, deconstruction, and formatting utilities for <see cref="Vector3d"/>.
 16/// </content>
 17public partial struct Vector3d
 18{
 19    /// <summary>
 20    /// Returns a string that represents the current object in the format "(x, y, z)".
 21    /// </summary>
 22    /// <returns>A string representation of the object, displaying the x, y, and z values in a formatted tuple.</returns
 23    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 4524    public override string ToString() => ToString(null, CultureInfo.InvariantCulture);
 25
 26    /// <summary>
 27    /// Returns a string that represents the current object in the format "(x, y, z)".
 28    /// </summary>
 29    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 30    public string ToString(string? format, IFormatProvider? formatProvider)
 31    {
 4932        Vector3d value = this;
 4933        return FixedDiagnosticsFormatter.ToString((Span<char> destination, out int charsWritten) =>
 4934            value.TryFormat(destination, out charsWritten, format.AsSpan(), formatProvider));
 35    }
 36
 37    /// <summary>
 38    /// Formats this vector into the provided destination buffer.
 39    /// </summary>
 40    public bool TryFormat(
 41        Span<char> destination,
 42        out int charsWritten,
 43        ReadOnlySpan<char> format,
 44        IFormatProvider? provider)
 45    {
 69646        int written = 0;
 69647        if (!FixedDiagnosticsFormatter.Append('(', destination, ref written) ||
 69648            !FixedDiagnosticsFormatter.Append(X, destination, ref written, format, provider) ||
 69649            !FixedDiagnosticsFormatter.Append(", ", destination, ref written) ||
 69650            !FixedDiagnosticsFormatter.Append(Y, destination, ref written, format, provider) ||
 69651            !FixedDiagnosticsFormatter.Append(", ", destination, ref written) ||
 69652            !FixedDiagnosticsFormatter.Append(Z, destination, ref written, format, provider) ||
 69653            !FixedDiagnosticsFormatter.Append(')', destination, ref written))
 54        {
 3855            charsWritten = 0;
 3856            return false;
 57        }
 58
 65859        charsWritten = written;
 65860        return true;
 61    }
 62
 63    /// <summary>
 64    /// Converts this <see cref="Vector3d"/> to a <see cref="Vector2d"/>,
 65    /// dropping the Y component (height) of this vector in the resulting vector.
 66    /// </summary>
 67    /// <returns>
 68    /// A new <see cref="Vector2d"/> where (X, Z) from this <see cref="Vector3d"/>
 69    /// become (X, Y) in the resulting vector.
 70    /// </returns>
 71    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 219572    public Vector2d ToVector2d() => new(X, Z);
 73
 74    /// <summary>
 75    /// Converts this <see cref="Vector3d"/> to a <see cref="Vector4d"/> with an explicit W component.
 76    /// </summary>
 77    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 378    public Vector4d ToVector4d(Fixed64 w) => new(X, Y, Z, w);
 79
 80    /// <summary>
 81    /// Deconstructs the Vector3d into its three Fixed64 components.
 82    /// </summary>
 83    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 84    public void Deconstruct(out Fixed64 x, out Fixed64 y, out Fixed64 z)
 85    {
 186        x = X;
 187        y = Y;
 188        z = Z;
 189    }
 90
 91    /// <summary>
 92    /// Deconstructs the Vector3d into its three int components.
 93    /// </summary>
 94    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 95    public void Deconstruct(out int x, out int y, out int z)
 96    {
 197        x = X.RoundToInt();
 198        y = Y.RoundToInt();
 199        z = Z.RoundToInt();
 1100    }
 101
 102    /// <summary>
 103    /// Deconstructs the Vector3d into its three long components.
 104    /// </summary>
 105    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 106    public void Deconstruct(out long x, out long y, out long z)
 107    {
 1108        x = X.m_rawValue;
 1109        y = Y.m_rawValue;
 1110        z = Z.m_rawValue;
 1111    }
 112
 113    /// <summary>
 114    /// Deconstructs the Vector3d into its three double components.
 115    /// </summary>
 116    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 117    public void Deconstruct(out double x, out double y, out double z)
 118    {
 1119        x = (double)X;
 1120        y = (double)Y;
 1121        z = (double)Z;
 1122    }
 123
 124    /// <summary>
 125    /// Converts each component of the vector from radians to degrees.
 126    /// </summary>
 127    /// <param name="radians">The vector with components in radians.</param>
 128    /// <returns>A new vector with components converted to degrees.</returns>
 129    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 130    public static Vector3d ToDegrees(Vector3d radians) =>
 1131         new(FixedMath.RadToDeg(radians.X),
 1132             FixedMath.RadToDeg(radians.Y),
 1133             FixedMath.RadToDeg(radians.Z));
 134
 135    /// <summary>
 136    /// Converts each component of the vector from degrees to radians.
 137    /// </summary>
 138    /// <param name="degrees">The vector with components in degrees.</param>
 139    /// <returns>A new vector with components converted to radians.</returns>
 140    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 141    public static Vector3d ToRadians(Vector3d degrees) =>
 1142        new(FixedMath.DegToRad(degrees.X),
 1143            FixedMath.DegToRad(degrees.Y),
 1144            FixedMath.DegToRad(degrees.Z));
 145}

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

#LineLine coverage
 1//=======================================================================
 2// Vector3d.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 3D vector with fixed-point precision, supporting a wide range of vector operations such as rotation, sc
 19/// </summary>
 20/// <remarks>
 21/// The Vector3d struct is designed for high-precision applications in 3D space, including games, simulations, and physi
 22/// It offers essential operations like addition, subtraction, dot product, cross product, distance calculation, and nor
 23///
 24/// FixedMathSharp's canonical 3D basis is <c>+X</c> right, <c>+Y</c> up, and <c>+Z</c>
 25/// forward. Direction-named core APIs use that convention; engine-specific naming, basis,
 26/// handedness, and matrix semantics should be converted at adapter boundaries.
 27///
 28/// Use Cases:
 29/// - Modeling 3D positions, directions, and velocities with fixed-point precision.
 30/// - Performing vector transformations, including rotations using quaternions.
 31/// - Calculating distances, angles, projections, and interpolation between vectors.
 32/// - Essential for fixed-point math scenarios where floating-point precision isn't suitable.
 33/// </remarks>
 34[Serializable]
 35[MemoryPackable]
 36public partial struct Vector3d : IEquatable<Vector3d>, IComparable<Vector3d>, IEqualityComparer<Vector3d>, IFormattable
 37#if NET8_0_OR_GREATER
 38    , ISpanFormattable
 39#endif
 40{
 41    #region Static Readonly Fields
 42
 43    /// <summary>
 44    /// The upward direction vector in the canonical 3D basis (0, 1, 0).
 45    /// </summary>
 866846    public static Vector3d Up => new(0, 1, 0);
 47
 48    /// <summary>
 49    /// The right direction vector in the canonical 3D basis (1, 0, 0).
 50    /// </summary>
 1311051    public static Vector3d Right => new(1, 0, 0);
 52
 53    /// <summary>
 54    /// The downward direction vector in the canonical 3D basis (0, -1, 0).
 55    /// </summary>
 7156    public static Vector3d Down => new(0, -1, 0);
 57
 58    /// <summary>
 59    /// The left direction vector in the canonical 3D basis (-1, 0, 0).
 60    /// </summary>
 6161    public static Vector3d Left => new(-1, 0, 0);
 62
 63    /// <summary>
 64    /// The forward direction vector in the canonical 3D basis (0, 0, 1).
 65    /// </summary>
 66    /// <remarks>
 67    /// FixedMathSharp defines semantic forward as <c>+Z</c>. Use
 68    /// <see cref="CoordinateConvention3d"/> at adapter boundaries when an external API uses
 69    /// different semantic axes, such as <c>-Z</c> forward or <c>+X</c> forward with <c>+Z</c> up.
 70    /// </remarks>
 44071    public static Vector3d Forward => new(0, 0, 1);
 72
 73    /// <summary>
 74    /// The backward direction vector in the canonical 3D basis (0, 0, -1).
 75    /// </summary>
 2476    public static Vector3d Backward => new(0, 0, -1);
 77
 78    /// <summary>
 79    /// (1, 1, 1)
 80    /// </summary>
 1136981    public static Vector3d One => new(1, 1, 1);
 82
 83    /// <summary>
 84    /// (-1, -1, -1)
 85    /// </summary>
 286    public static Vector3d Negative => new(-1, -1, -1);
 87
 88    /// <summary>
 89    /// (0, 0, 0)
 90    /// </summary>
 8098691    public static Vector3d Zero => new(0, 0, 0);
 92
 93    #endregion
 94    #region Fields
 95
 96    /// <summary>
 97    /// The X component of the vector.
 98    /// </summary>
 99    [JsonInclude]
 100    [MemoryPackOrder(0)]
 101    public Fixed64 X;
 102
 103    /// <summary>
 104    /// The Y component of the vector.
 105    /// </summary>
 106    [JsonInclude]
 107    [MemoryPackOrder(1)]
 108    public Fixed64 Y;
 109
 110    /// <summary>
 111    /// The Z component of the vector.
 112    /// </summary>
 113    [JsonInclude]
 114    [MemoryPackOrder(2)]
 115    public Fixed64 Z;
 116
 117    #endregion
 118    #region Constructors
 119
 120    /// <summary>
 121    /// Initializes a new instance of the Vector3d structure using integer values for the X, Y, and Z components.
 122    /// </summary>
 123    /// <param name="xInt">The value of the X component as an integer.</param>
 124    /// <param name="yInt">The value of the Y component as an integer.</param>
 125    /// <param name="zInt">The value of the Z component as an integer.</param>
 236068126    public Vector3d(int xInt, int yInt, int zInt) : this((Fixed64)xInt, (Fixed64)yInt, (Fixed64)zInt) { }
 127
 128    /// <summary>
 129    /// Initializes a new instance of the Vector3d structure with the specified X, Y, and Z components.
 130    /// </summary>
 131    /// <param name="x">The value of the X component of the vector.</param>
 132    /// <param name="y">The value of the Y component of the vector.</param>
 133    /// <param name="z">The value of the Z component of the vector.</param>
 134    [JsonConstructor]
 135    public Vector3d(Fixed64 x, Fixed64 y, Fixed64 z)
 136    {
 276828137        X = x;
 276828138        Y = y;
 276828139        Z = z;
 276828140    }
 141
 142    /// <summary>
 143    /// Initializes a new instance of the Vector3d structure using the specified X, Y, and Z coordinates as
 144    /// double-precision floating-point values.
 145    /// </summary>
 146    /// <remarks>This constructor allows for convenient creation of a Vector3d from double values, which are
 147    /// internally converted to the Fixed64 representation used by the structure. Components are converted
 148    /// through <see cref="Fixed64.FromDouble(double)"/>, so non-finite values throw
 149    /// <see cref="ArgumentOutOfRangeException"/> and finite values outside the Q32.32 range throw
 150    /// <see cref="OverflowException"/>.</remarks>
 151    /// <param name="xDoub">The X coordinate of the vector, specified as a double-precision floating-point value.</param
 152    /// <param name="yDoub">The Y coordinate of the vector, specified as a double-precision floating-point value.</param
 153    /// <param name="zDoub">The Z coordinate of the vector, specified as a double-precision floating-point value.</param
 154    public static Vector3d FromDouble(double xDoub, double yDoub, double zDoub) =>
 48155        new(Fixed64.FromDouble(xDoub),
 48156            Fixed64.FromDouble(yDoub),
 48157            Fixed64.FromDouble(zDoub));
 158
 159    #endregion
 160    #region Properties
 161
 162    /// <summary>
 163    ///  Provides a rotated version of the current vector, where rotation is a 90 degrees rotation around the Y axis in 
 164    /// </summary>
 165    /// <remarks>
 166    /// These operations rotate the vector 90 degrees around the Y-axis.
 167    /// Note that the positive direction of rotation is defined by the right-hand rule:
 168    /// If your right hand's thumb points in the positive Y direction, then your fingers curl in the positive direction 
 169    /// </remarks>
 170    [JsonIgnore]
 171    [MemoryPackIgnore]
 172    public Vector3d RightHandNormal
 173    {
 174        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1175        get => new(Z, Y, -X);
 176    }
 177
 178    /// <summary>
 179    /// Provides a rotated version of the current vector, where rotation is a 90 degrees rotation around the Y axis in t
 180    /// </summary>
 181    [JsonIgnore]
 182    [MemoryPackIgnore]
 183    public Vector3d LeftHandNormal
 184    {
 185        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1186        get => new(-Z, Y, X);
 187    }
 188
 189    /// <inheritdoc cref="GetNormalized(Vector3d)"/>
 190    [JsonIgnore]
 191    [MemoryPackIgnore]
 192    public Vector3d Normalized
 193    {
 194        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 199195        get => GetNormalized(this);
 196    }
 197
 198    /// <summary>
 199    /// Returns the actual length of this vector (RO).
 200    /// </summary>
 201    [JsonIgnore]
 202    [MemoryPackIgnore]
 203    public Fixed64 Magnitude
 204    {
 205        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 14179206        get => GetMagnitude(this);
 207    }
 208
 209    /// <summary>
 210    /// This vector's squared magnitude (aka length squared).
 211    /// If you're doing distance checks, use MagnitudeSquared and square the distance you're checking against.
 212    /// If you need to know the actual distance, use Magnitude.
 213    /// </summary>
 214    /// <returns>The magnitude.</returns>
 215    [JsonIgnore]
 216    [MemoryPackIgnore]
 217    public Fixed64 MagnitudeSquared
 218    {
 219        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 7667220        get => (X * X) + (Y * Y) + (Z * Z);
 221    }
 222
 223    /// <summary>
 224    /// Calculates the forward direction vector from pitch (x) and yaw (y) angles.
 225    /// </summary>
 226    /// <remarks>
 227    /// This is commonly used to determine the direction an object is facing in 3D space,
 228    /// where 'x' represents pitch around the X axis and 'y' represents yaw around the Y axis.
 229    /// At zero pitch and yaw this returns <see cref="Forward"/>.
 230    /// Positive pitch rotates the forward direction toward <see cref="Down"/>.
 231    /// </remarks>
 232    [JsonIgnore]
 233    [MemoryPackIgnore]
 234    public Vector3d Direction
 235    {
 236        get
 237        {
 9238            Fixed64 temp1 = FixedMath.Cos(X) * FixedMath.Sin(Y);
 9239            Fixed64 temp2 = FixedMath.Sin(-X);
 9240            Fixed64 temp3 = FixedMath.Cos(X) * FixedMath.Cos(Y);
 9241            return new Vector3d(temp1, temp2, temp3);
 242        }
 243    }
 244
 245    /// <summary>
 246    /// Are all components of this vector equal to zero?
 247    /// </summary>
 248    /// <returns></returns>
 249    [JsonIgnore]
 250    [MemoryPackIgnore]
 251    public bool IsZero
 252    {
 253        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 147254        get => Equals(Zero);
 255    }
 256
 257    /// <summary>
 258    /// Returns a long hash of the vector based on its x, y, and z values.
 259    /// </summary>
 260    [JsonIgnore]
 261    [MemoryPackIgnore]
 262    public long LongStateHash
 263    {
 264        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 4670265        get => (X.m_rawValue * 31) + (Y.m_rawValue * 7) + (Z.m_rawValue * 11);
 266    }
 267
 268    /// <summary>
 269    /// Returns a hash of the vector based on its state.
 270    /// </summary>
 271    [JsonIgnore]
 272    [MemoryPackIgnore]
 273    public int StateHash
 274    {
 275        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 4670276        get => (int)(LongStateHash % int.MaxValue);
 277    }
 278
 279    /// <summary>
 280    /// Gets or sets the component value at the specified index.
 281    /// </summary>
 282    /// <remarks>
 283    /// Use this indexer to access or modify the x, y, or z components of the vector by index.
 284    /// Index 0 corresponds to x, 1 to y, and 2 to z.
 285    /// </remarks>
 286    /// <param name="index">The zero-based index of the component to access. Valid values are 0 (x), 1 (y), or 2 (z).</p
 287    /// <returns>The value of the component at the specified index.</returns>
 288    /// <exception cref="IndexOutOfRangeException">Thrown if index is less than 0 or greater than 2.</exception>
 289    [JsonIgnore]
 290    [MemoryPackIgnore]
 291    public Fixed64 this[int index]
 292    {
 293        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 294        get
 295        {
 2189296            return index switch
 2189297            {
 1229298                0 => X,
 645299                1 => Y,
 313300                2 => Z,
 2301                _ => throw new IndexOutOfRangeException("Invalid Vector3d index!"),
 2189302            };
 303        }
 304        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 305        set
 306        {
 307            switch (index)
 308            {
 309                case 0:
 9310                    X = value;
 9311                    break;
 312                case 1:
 9313                    Y = value;
 9314                    break;
 315                case 2:
 9316                    Z = value;
 9317                    break;
 318                default:
 2319                    throw new IndexOutOfRangeException("Invalid Vector3d index!");
 320            }
 321        }
 322    }
 323
 324    #endregion
 325    #region Methods (Instance)
 326
 327    /// <summary>
 328    /// Set x, y and z components of an existing Vector3.
 329    /// </summary>
 330    /// <param name="newX"></param>
 331    /// <param name="newY"></param>
 332    /// <param name="newZ"></param>
 333    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 334    public Vector3d Set(Fixed64 newX, Fixed64 newY, Fixed64 newZ)
 335    {
 1336        X = newX;
 1337        Y = newY;
 1338        Z = newZ;
 1339        return this;
 340    }
 341
 342    /// <summary>
 343    /// Adds the specified values to the components of the vector in place and returns the modified vector.
 344    /// </summary>
 345    /// <param name="xAmount">The amount to add to the x component.</param>
 346    /// <param name="yAmount">The amount to add to the y component.</param>
 347    /// <param name="zAmount">The amount to add to the z component.</param>
 348    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 349    public Vector3d AddInPlace(Fixed64 xAmount, Fixed64 yAmount, Fixed64 zAmount)
 350    {
 4351        X += xAmount;
 4352        Y += yAmount;
 4353        Z += zAmount;
 4354        return this;
 355    }
 356
 357    /// <summary>
 358    /// Adds the specified values to the components of the vector in place and returns the modified vector.
 359    /// </summary>
 360    /// <param name="amount">The amount to add to the components.</param>
 361    /// <returns>The modified vector after addition.</returns>
 362    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1363    public Vector3d AddInPlace(Fixed64 amount) => AddInPlace(amount, amount, amount);
 364
 365    /// <summary>
 366    /// Adds the specified vector components to the corresponding components of the in place vector and returns the modi
 367    /// </summary>
 368    /// <param name="other">The other vector to add the components.</param>
 369    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2370    public Vector3d AddInPlace(Vector3d other) => AddInPlace(other.X, other.Y, other.Z);
 371
 372    /// <summary>
 373    /// Subtracts the specified values from the components of the vector in place and returns the modified vector.
 374    /// </summary>
 375    /// <param name="xAmount">The amount to subtract from the x component.</param>
 376    /// <param name="yAmount">The amount to subtract from the y component.</param>
 377    /// <param name="zAmount">The amount to subtract from the z component.</param>
 378    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 379    public Vector3d SubtractInPlace(Fixed64 xAmount, Fixed64 yAmount, Fixed64 zAmount)
 380    {
 4381        X -= xAmount;
 4382        Y -= yAmount;
 4383        Z -= zAmount;
 4384        return this;
 385    }
 386
 387    /// <summary>
 388    /// Subtracts the specified value from all components of the vector in place and returns the modified vector.
 389    /// </summary>
 390    /// <param name="amount">The amount to subtract from each component.</param>
 391    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2392    public Vector3d SubtractInPlace(Fixed64 amount) => SubtractInPlace(amount, amount, amount);
 393
 394    /// <summary>
 395    /// Subtracts the specified vector from the components of the vector in place and returns the modified vector.
 396    /// </summary>
 397    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1398    public Vector3d SubtractInPlace(Vector3d other) => SubtractInPlace(other.X, other.Y, other.Z);
 399
 400    /// <summary>
 401    /// Multiplies each component of the vector by the corresponding factor in place and returns the modified vector.
 402    /// </summary>
 403    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 404    public Vector3d MultiplyInPlace(Fixed64 factorX, Fixed64 factorY, Fixed64 factorZ)
 405    {
 4406        X *= factorX;
 4407        Y *= factorY;
 4408        Z *= factorZ;
 4409        return this;
 410    }
 411
 412    /// <summary>
 413    /// Multiplies the components of the vector by the specified scalar factor in place and returns the modified vector.
 414    /// </summary>
 415    /// <param name="factor">The scalar factor to multiply each component by.</param>
 416    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2417    public Vector3d MultiplyInPlace(Fixed64 factor) => MultiplyInPlace(factor, factor, factor);
 418
 419    /// <summary>
 420    /// Multiplies each component of the vector by the corresponding component of the given vector in place and returns 
 421    /// </summary>
 422    /// <param name="factor">The vector containing the multiplication factors for each component.</param>
 423    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1424    public Vector3d MultiplyInPlace(Vector3d factor) => MultiplyInPlace(factor.X, factor.Y, factor.Z);
 425
 426    /// <summary>
 427    /// Divides each component of the vector by the corresponding divisor in place and returns the modified vector.
 428    /// </summary>
 429    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 430    public Vector3d DivideInPlace(Fixed64 divisorX, Fixed64 divisorY, Fixed64 divisorZ)
 431    {
 5432        X = divisorX == Fixed64.Zero ? Fixed64.Zero : X / divisorX;
 5433        Y = divisorY == Fixed64.Zero ? Fixed64.Zero : Y / divisorY;
 5434        Z = divisorZ == Fixed64.Zero ? Fixed64.Zero : Z / divisorZ;
 5435        return this;
 436    }
 437
 438    /// <summary>
 439    /// Divides each component of the vector by the specified scalar divisor in place and returns the modified vector.
 440    /// </summary>
 441    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 442    public Vector3d DivideInPlace(Fixed64 divisor)
 443    {
 2444        if (divisor == Fixed64.Zero)
 1445            return this = Zero;
 446
 1447        X /= divisor;
 1448        Y /= divisor;
 1449        Z /= divisor;
 1450        return this;
 451    }
 452
 453    /// <summary>
 454    /// Divides each component of the vector by the corresponding component of the given vector in place and returns the
 455    /// </summary>
 456    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2457    public Vector3d DivideInPlace(Vector3d divisor) => DivideInPlace(divisor.X, divisor.Y, divisor.Z);
 458
 459    /// <summary>
 460    /// Normalizes this vector in place, making its magnitude (length) equal to 1, and returns the modified vector.
 461    /// </summary>
 462    /// <remarks>
 463    /// If the vector is zero-length or already normalized, no operation is performed.
 464    /// This method modifies the current vector in place and supports method chaining.
 465    /// </remarks>
 466    /// <returns>The normalized vector.</returns>
 467    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 47468    public Vector3d NormalizeInPlace() => this = GetNormalized(this);
 469
 470    /// <summary>
 471    /// Normalizes this vector in place and outputs its original magnitude.
 472    /// </summary>
 473    /// <remarks>
 474    /// If the vector is zero-length or already normalized, no operation is performed, but the original magnitude will s
 475    /// </remarks>
 476    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 477    public Vector3d NormalizeInPlace(out Fixed64 mag)
 478    {
 15479        Vector3d source = this;
 15480        bool magnitudeIsRepresentable = TryGetMagnitude(
 15481            source,
 15482            out mag,
 15483            out bool isNormalized);
 484
 485        // If magnitude is zero, return a zero vector to avoid divide-by-zero errors
 15486        if (mag == Fixed64.Zero)
 487        {
 1488            X = Fixed64.Zero;
 1489            Y = Fixed64.Zero;
 1490            Z = Fixed64.Zero;
 1491            return this;
 492        }
 493
 14494        if (isNormalized)
 1495            return this;
 496
 13497        if (!magnitudeIsRepresentable || mag == Fixed64.One)
 1498            return this = WideNormalization.GetNormalized(source);
 499
 12500        if (mag <= FixedMath.ScaleSafeMagnitudeThreshold)
 1501            return this = GetScaleNormalized(source);
 502
 11503        X = FixedMath.FastDiv(X, mag);
 11504        Y = FixedMath.FastDiv(Y, mag);
 11505        Z = FixedMath.FastDiv(Z, mag);
 506
 11507        return IsNormalized()
 11508            ? this
 11509            : this = WideNormalization.GetNormalized(source);
 510    }
 511
 512    /// <summary>
 513    /// Checks whether the nonzero squared magnitude is within
 514    /// <see cref="Fixed64.Epsilon"/> of 1.
 515    /// </summary>
 516    public bool IsNormalized()
 517    {
 7312518        Fixed64 sqrMagnitude = MagnitudeSquared;
 7312519        return sqrMagnitude != Fixed64.Zero && FixedMath.Abs(sqrMagnitude - Fixed64.One) <= Fixed64.Epsilon;
 520    }
 521
 522    /// <summary>
 523    /// Attempts to return this vector's magnitude rounded outward to the
 524    /// smallest containing Q32.32 value.
 525    /// </summary>
 526    /// <returns>
 527    /// <see langword="false"/> only when the final ceiling exceeds the
 528    /// positive <see cref="Fixed64"/> domain.
 529    /// </returns>
 530    public readonly bool TryGetMagnitudeCeiling(
 531        out Fixed64 magnitude) =>
 3532        WideGeometry.TryGetMagnitudeCeiling(
 3533            X,
 3534            Y,
 3535            Z,
 3536            out magnitude);
 537
 538    /// <summary>
 539    /// Checks whether all components are strictly greater than <see cref="Fixed64.Epsilon"/>.
 540    /// </summary>
 541    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 542    public bool AllComponentsGreaterThanEpsilon() =>
 2543        X.Abs() > Fixed64.Epsilon && Y.Abs() > Fixed64.Epsilon && Z.Abs() > Fixed64.Epsilon;
 544
 545    /// <summary>
 546    /// Returns a new vector with components whose absolute values are less than the specified threshold set to zero.
 547    /// </summary>
 548    /// <remarks>
 549    /// This method is useful for eliminating insignificant floating-point errors by zeroing out very small vector compo
 550    /// The default threshold is suitable for most cases where near-zero values are considered noise.
 551    /// </remarks>
 552    /// <param name="threshold">
 553    /// The minimum absolute value a component must have to be retained.
 554    /// If null, a default epsilon value is used.
 555    /// </param>
 556    /// <returns>A new Vector3d instance with small components snapped to zero based on the specified threshold.</return
 557    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 558    public Vector3d SnapSmallComponentsToZero(Fixed64? threshold = null)
 559    {
 3560        Fixed64 effectiveThreshold = threshold ?? Fixed64.Epsilon;
 3561        return new Vector3d(
 3562            X.Abs() < effectiveThreshold ? Fixed64.Zero : X,
 3563            Y.Abs() < effectiveThreshold ? Fixed64.Zero : Y,
 3564            Z.Abs() < effectiveThreshold ? Fixed64.Zero : Z
 3565        );
 566    }
 567
 568    /// <summary>
 569    /// Computes the distance between this vector and another vector.
 570    /// </summary>
 571    /// <param name="otherX">The x component of the other vector.</param>
 572    /// <param name="otherY">The y component of the other vector.</param>
 573    /// <param name="otherZ">The z component of the other vector.</param>
 574    /// <returns>The distance between the two vectors.</returns>
 575    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 576    public Fixed64 Distance(Fixed64 otherX, Fixed64 otherY, Fixed64 otherZ)
 577    {
 36578        Fixed64 deltaX = X - otherX;
 36579        Fixed64 deltaY = Y - otherY;
 36580        Fixed64 deltaZ = Z - otherZ;
 36581        Fixed64 squareSum = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;
 36582        return squareSum == Fixed64.MaxValue
 36583            ? FixedMath.GetScaledMagnitude(deltaX, deltaY, deltaZ, Fixed64.Zero)
 36584            : FixedMath.Sqrt(squareSum);
 585    }
 586
 587    /// <summary>
 588    /// Calculates the squared distance between two vectors, avoiding the need for a square root operation.
 589    /// </summary>
 590    /// <returns>The squared distance between the two vectors.</returns>
 591    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 592    public Fixed64 DistanceSquared(Fixed64 otherX, Fixed64 otherY, Fixed64 otherZ)
 593    {
 100594        Fixed64 temp1 = X - otherX;
 100595        temp1 *= temp1;
 100596        Fixed64 temp2 = Y - otherY;
 100597        temp2 *= temp2;
 100598        Fixed64 temp3 = Z - otherZ;
 100599        temp3 *= temp3;
 100600        return temp1 + temp2 + temp3;
 601    }
 602
 603    /// <summary>
 604    /// Computes the dot product of this vector with another vector specified by its components.
 605    /// </summary>
 606    /// <param name="otherX">The x component of the other vector.</param>
 607    /// <param name="otherY">The y component of the other vector.</param>
 608    /// <param name="otherZ">The z component of the other vector.</param>
 609    /// <returns>The dot product of the two vectors.</returns>
 610    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 611    public Fixed64 Dot(Fixed64 otherX, Fixed64 otherY, Fixed64 otherZ) =>
 32658612        X * otherX + Y * otherY + Z * otherZ;
 613
 614    /// <summary>
 615    /// Computes the cross product magnitude of this vector with another vector.
 616    /// </summary>
 617    /// <param name="otherX">The X component of the other vector.</param>
 618    /// <param name="otherY">The Y component of the other vector.</param>
 619    /// <param name="otherZ">The Z component of the other vector.</param>
 620    /// <returns>The cross product magnitude.</returns>
 621    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 622    public Fixed64 CrossProduct(Fixed64 otherX, Fixed64 otherY, Fixed64 otherZ) =>
 5623        (Y * otherZ - Z * otherY) + (Z * otherX - X * otherZ) + (X * otherY - Y * otherX);
 624
 625    /// <summary>
 626    /// Returns the cross vector of this vector with another vector.
 627    /// </summary>
 628    /// <returns>A new vector representing the cross product.</returns>
 629    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 630    public Vector3d Cross(Fixed64 otherX, Fixed64 otherY, Fixed64 otherZ) =>
 6208631        new(Y * otherZ - Z * otherY,
 6208632            Z * otherX - X * otherZ,
 6208633            X * otherY - Y * otherX);
 634
 635    #endregion
 636}

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

#LineLine coverage
 1//=======================================================================
 2// Vector3d.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="Vector3d"/>.
 14/// </content>
 15public partial struct Vector3d
 16{
 17    /// <inheritdoc/>
 18    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 6819    public override bool Equals(object? obj) => obj is Vector3d other && Equals(other);
 20
 21    /// <inheritdoc/>
 22    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1829823    public bool Equals(Vector3d other) => other.X == X && other.Y == Y && other.Z == Z;
 24
 25    /// <inheritdoc/>
 226    public bool Equals(Vector3d x, Vector3d y) => x.Equals(y);
 27
 28    /// <inheritdoc/>
 29    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 363230    public override int GetHashCode() => StateHash;
 31
 32    /// <inheritdoc/>
 133    public int GetHashCode(Vector3d obj) => obj.GetHashCode();
 34
 35    /// <summary>
 36    /// Compares the current Vector3d instance with another Vector3d based on their squared magnitudes.
 37    /// </summary>
 38    /// <remarks>
 39    /// This comparison uses the squared magnitude of each vector, which avoids the computational
 40    /// cost of calculating the actual magnitude.
 41    /// Use this method when only relative vector lengths are
 42    /// important.
 43    /// </remarks>
 44    /// <param name="other">The Vector3d instance to compare with the current instance.</param>
 45    /// <returns>A value less than zero if this instance is less than <paramref name="other"/>; zero if this instance is
 46    /// <paramref name="other"/>; or a value greater than zero if this instance is greater than <paramref
 47    /// name="other"/>, as determined by their squared magnitudes.</returns>
 148    public int CompareTo(Vector3d other) => MagnitudeSquared.CompareTo(other.MagnitudeSquared);
 49}

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

#LineLine coverage
 1//=======================================================================
 2// Vector3d.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/// Defines arithmetic and comparison operators for <see cref="Vector3d"/>.
 14/// </content>
 15public partial struct Vector3d
 16{
 17    /// <summary>
 18    /// Adds two Vector3d 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 Vector3d whose components are the sum of the corresponding components of v1 and v2.</returns>
 23    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 507824    public static Vector3d operator +(Vector3d v1, Vector3d v2) => new(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
 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 Vector3d whose components are the sum of the corresponding components of the input vector and the
 32    /// value.</returns>
 33    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 234    public static Vector3d operator +(Vector3d v1, Fixed64 mag) => new(v1.X + mag, v1.Y + mag, v1.Z + mag);
 35
 36    /// <inheritdoc cref="operator +(Vector3d, Fixed64)"/>
 37    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 138    public static Vector3d operator +(Fixed64 mag, Vector3d v1) => v1 + mag;
 39
 40    /// <summary>
 41    /// Adds a Vector3d instance to a tuple representing x, y, and z components and returns the resulting vector.
 42    /// </summary>
 43    /// <param name="v1">The first vector to add.</param>
 44    /// <param name="v2">A tuple containing the x, y, and z values to add to the vector.</param>
 45    /// <returns>A new Vector3d that is the sum of the original vector and the specified tuple components.</returns>
 46    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 247    public static Vector3d operator +(Vector3d v1, (int x, int y, int z) v2) => new(v1.X + v2.x, v1.Y + v2.y, v1.Z + v2.
 48
 49    /// <summary>
 50    /// Adds a 3-tuple of integers to a Vector3d instance, returning the resulting vector.
 51    /// </summary>
 52    /// <param name="v2">A tuple containing the X, Y, and Z components to add to the vector.</param>
 53    /// <param name="v1">The Vector3d instance to which the tuple components are added.</param>
 54    /// <returns>A new Vector3d representing the sum of the original vector and the specified tuple components.</returns
 55    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 156    public static Vector3d operator +((int x, int y, int z) v2, Vector3d v1) => v1 + v2;
 57
 58    /// <summary>
 59    /// Subtracts the components of one Vector3d from another and returns the resulting vector.
 60    /// </summary>
 61    /// <param name="v1">The vector to subtract from.</param>
 62    /// <param name="v2">The vector to subtract.</param>
 63    /// <returns>A Vector3d whose components are the result of subtracting the corresponding components of v2 from v1.</
 64    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 471465    public static Vector3d operator -(Vector3d v1, Vector3d v2) => new(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
 66
 67    /// <summary>
 68    /// Subtracts the specified scalar value from each component of the given vector.
 69    /// </summary>
 70    /// <param name="v1">The vector from which to subtract the scalar value from each component.</param>
 71    /// <param name="mag">The scalar value to subtract from each component of the vector.</param>
 72    /// <returns>A new Vector3d whose components are the result of subtracting the scalar value from the corresponding c
 73    /// of the input vector.</returns>
 74    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 175    public static Vector3d operator -(Vector3d v1, Fixed64 mag) => new(v1.X - mag, v1.Y - mag, v1.Z - mag);
 76
 77    /// <summary>
 78    /// Subtracts the specified tuple from the given vector and returns the resulting vector.
 79    /// </summary>
 80    /// <param name="v1">The vector from which to subtract the tuple values.</param>
 81    /// <param name="v2">A tuple containing the x, y, and z values to subtract from the vector.</param>
 82    /// <returns>A new Vector3d representing the result of subtracting the tuple values from the original vector.</retur
 83    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 184    public static Vector3d operator -(Vector3d v1, (int x, int y, int z) v2) => new(v1.X - v2.x, v1.Y - v2.y, v1.Z - v2.
 85
 86    /// <summary>
 87    /// Subtracts the components of a specified Vector3d from the corresponding components of a 3-tuple of integers and
 88    /// returns the resulting Vector3d.
 89    /// </summary>
 90    /// <remarks>This operator enables direct subtraction between a tuple of three integers and a Vector3d,
 91    /// returning a new Vector3d instance.</remarks>
 92    /// <param name="v1">A tuple containing the x, y, and z components to subtract from.</param>
 93    /// <param name="v2">The Vector3d whose components are subtracted from the corresponding components of the tuple.</p
 94    /// <returns>A Vector3d whose components are the result of subtracting the components of v2 from the corresponding c
 95    /// of v1.</returns>
 96    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 197    public static Vector3d operator -((int x, int y, int z) v1, Vector3d v2) => new(v1.x - v2.X, v1.y - v2.Y, v1.z - v2.
 98
 99    /// <summary>
 100    /// Negates each component of the specified vector.
 101    /// </summary>
 102    /// <param name="v1">The vector whose components are to be negated.</param>
 103    /// <returns>A new vector whose components are the negated values of the input vector.</returns>
 104    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 4680105    public static Vector3d operator -(Vector3d v1) => new(v1.X * -Fixed64.One, v1.Y * -Fixed64.One, v1.Z * -Fixed64.One)
 106
 107    /// <summary>
 108    /// Multiplies the specified vector by a scalar value.
 109    /// </summary>
 110    /// <param name="v1">The vector to be scaled.</param>
 111    /// <param name="mag">The scalar value by which to multiply each component of the vector.</param>
 112    /// <returns>A new vector whose components are the products of the corresponding components of the input vector and 
 113    /// scalar value.</returns>
 114    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 20415115    public static Vector3d operator *(Vector3d v1, Fixed64 mag) => new(v1.X * mag, v1.Y * mag, v1.Z * mag);
 116
 117    /// <inheritdoc cref="operator *(Vector3d, Fixed64)"/>
 118    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 10119    public static Vector3d operator *(Fixed64 mag, Vector3d v1) => new(v1.X * mag, v1.Y * mag, v1.Z * mag);
 120
 121    /// <summary>
 122    /// Multiplies each component of the specified vector by the given scalar value.
 123    /// </summary>
 124    /// <param name="v1">The vector whose components are to be multiplied.</param>
 125    /// <param name="mag">The scalar value by which to multiply each component of the vector.</param>
 126    /// <returns>A new Vector3d whose components are the products of the corresponding components of the input vector an
 127    /// scalar value.</returns>
 128    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 3129    public static Vector3d operator *(Vector3d v1, int mag) => new(v1.X * mag, v1.Y * mag, v1.Z * mag);
 130
 131    /// <inheritdoc cref="operator *(Vector3d, int)"/>
 132    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1133    public static Vector3d operator *(int mag, Vector3d v1) => new(v1.X * mag, v1.Y * mag, v1.Z * mag);
 134
 135    /// <summary>
 136    /// Multiplies a 3x3 matrix by a 3-dimensional vector and returns the resulting vector.
 137    /// </summary>
 138    /// <remarks>
 139    /// This operation applies the linear transformation represented by the matrix to the vector.
 140    /// The multiplication is performed using standard matrix-vector multiplication rules.
 141    /// </remarks>
 142    /// <param name="matrix">The 3x3 matrix to multiply.</param>
 143    /// <param name="vector">The 3-dimensional vector to be transformed by the matrix.</param>
 144    /// <returns>A new Vector3d that is the result of multiplying the specified matrix by the specified vector.</returns
 145    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 146    public static Vector3d operator *(Fixed3x3 matrix, Vector3d vector) =>
 2147         new(vector.X * matrix.M11 + vector.Y * matrix.M21 + vector.Z * matrix.M31,
 2148             vector.X * matrix.M12 + vector.Y * matrix.M22 + vector.Z * matrix.M32,
 2149             vector.X * matrix.M13 + vector.Y * matrix.M23 + vector.Z * matrix.M33);
 150
 151    /// <inheritdoc cref="operator *(Fixed3x3, Vector3d)"/>
 152    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1153    public static Vector3d operator *(Vector3d vector, Fixed3x3 matrix) => matrix * vector;
 154
 155    /// <summary>
 156    /// Transforms the specified 3D vector by the given 4x4 matrix using homogeneous coordinates.
 157    /// </summary>
 158    /// <remarks>
 159    /// If the matrix is affine, the transformation is performed without perspective division.
 160    /// For non-affine matrices, the result is divided by the computed w component to account for perspective
 161    /// transformations.
 162    /// If the computed w component is zero, it is treated as one to avoid division by zero.
 163    /// </remarks>
 164    /// <param name="matrix">The 4x4 matrix to apply to the vector. Must represent a valid transformation.</param>
 165    /// <param name="point">The 3D vector to be transformed.</param>
 166    /// <returns>A new Vector3d representing the transformed vector after applying the matrix.</returns>
 167    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 168    public static Vector3d operator *(Fixed4x4 matrix, Vector3d point)
 169    {
 8170        if (matrix.IsAffine)
 171        {
 4172            return new Vector3d(
 4173                point.X * matrix.M11 + point.Y * matrix.M21 + point.Z * matrix.M31 + matrix.M41,
 4174                point.X * matrix.M12 + point.Y * matrix.M22 + point.Z * matrix.M32 + matrix.M42,
 4175                point.X * matrix.M13 + point.Y * matrix.M23 + point.Z * matrix.M33 + matrix.M43
 4176            );
 177        }
 178
 179        // Full 4×4 transformation
 4180        Fixed64 w = matrix.M14 * point.X + matrix.M24 * point.Y + matrix.M34 * point.Z + matrix.M44;
 6181        if (w == Fixed64.Zero) w = Fixed64.One;  // Prevent divide-by-zero
 182
 4183        return new Vector3d(
 4184            (point.X * matrix.M11 + point.Y * matrix.M21 + point.Z * matrix.M31 + matrix.M41) / w,
 4185            (point.X * matrix.M12 + point.Y * matrix.M22 + point.Z * matrix.M32 + matrix.M42) / w,
 4186            (point.X * matrix.M13 + point.Y * matrix.M23 + point.Z * matrix.M33 + matrix.M43) / w
 4187        );
 188    }
 189
 190    /// <inheritdoc cref="operator *(Fixed4x4, Vector3d)"/>
 191    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 3192    public static Vector3d operator *(Vector3d vector, Fixed4x4 matrix) => matrix * vector;
 193
 194    /// <summary>
 195    /// Multiplies the corresponding components of two vectors and returns the resulting vector.
 196    /// </summary>
 197    /// <remarks>
 198    /// This operation performs component-wise multiplication, not a dot or cross product.
 199    /// Each component of the result is calculated as the product of the corresponding components of the input
 200    /// vectors.
 201    /// </remarks>
 202    /// <param name="v1">The first vector to multiply.</param>
 203    /// <param name="v2">The second vector to multiply.</param>
 204    /// <returns>A new Vector3d whose components are the products of the corresponding components of the input vectors.<
 205    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 3206    public static Vector3d operator *(Vector3d v1, Vector3d v2) => new(v1.X * v2.X, v1.Y * v2.Y, v1.Z * v2.Z);
 207
 208    /// <summary>
 209    /// Divides each component of a vector by a specified scalar value.
 210    /// </summary>
 211    /// <remarks>If the scalar value is zero, the result is a zero vector to avoid division by zero.</remarks>
 212    /// <param name="v1">The vector whose components are to be divided.</param>
 213    /// <param name="div">The scalar value by which to divide each component of the vector.</param>
 214    /// <returns>
 215    /// A new vector whose components are the result of dividing the corresponding components of the input vector by the
 216    /// specified scalar.
 217    /// Returns a zero vector if the scalar is zero.
 218    /// </returns>
 219    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 220    public static Vector3d operator /(Vector3d v1, Fixed64 div) =>
 17505221        div == Fixed64.Zero
 17505222        ? Zero
 17505223        : new Vector3d(v1.X / div, v1.Y / div, v1.Z / div);
 224
 225    /// <summary>
 226    /// Divides each component of one vector by the corresponding component of another vector.
 227    /// </summary>
 228    /// <remarks>Division by zero for any component in v2 results in a zero value for the corresponding
 229    /// component in the result vector.</remarks>
 230    /// <param name="v1">The vector whose components are to be divided (the dividend).</param>
 231    /// <param name="v2">The vector whose components are used as divisors.</param>
 232    /// <returns>
 233    /// A new Vector3d whose components are the result of dividing the corresponding components of v1 by v2.
 234    /// If a component of v2 is zero, the corresponding result component is set to zero.
 235    /// </returns>
 236    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 237    public static Vector3d operator /(Vector3d v1, Vector3d v2) =>
 3238        new(v2.X == Fixed64.Zero ? Fixed64.Zero : v1.X / v2.X,
 3239            v2.Y == Fixed64.Zero ? Fixed64.Zero : v1.Y / v2.Y,
 3240            v2.Z == Fixed64.Zero ? Fixed64.Zero : v1.Z / v2.Z);
 241
 242    /// <summary>
 243    /// Divides each component of a vector by the specified integer value.
 244    /// </summary>
 245    /// <param name="v1">The vector whose components are to be divided.</param>
 246    /// <param name="div">The integer divisor. If zero, the result is a zero vector.</param>
 247    /// <returns>
 248    /// A new vector whose components are the result of dividing each component of the input vector by the specified
 249    /// divisor.
 250    /// Returns a zero vector if the divisor is zero.
 251    /// </returns>
 252    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 253    public static Vector3d operator /(Vector3d v1, int div) =>
 2254        div == 0
 2255        ? Zero
 2256        : new Vector3d(v1.X / div, v1.Y / div, v1.Z / div);
 257
 258    /// <summary>
 259    /// Rotates the specified 3D point by the given quaternion.
 260    /// </summary>
 261    /// <remarks>
 262    /// This operator applies the rotation to the point as if performing a geometric transformation in 3D space.</remark
 263    /// <param name="point">The 3D point to be rotated.</param>
 264    /// <param name="rotation">The quaternion representing the rotation to apply.</param>
 265    /// <returns>A new Vector3d representing the rotated point.</returns>
 266    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1267    public static Vector3d operator *(Vector3d point, FixedQuaternion rotation) => rotation * point;
 268
 269    /// <inheritdoc cref="operator *(Vector3d, FixedQuaternion)"/>
 270    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 271    public static Vector3d operator *(FixedQuaternion rotation, Vector3d point)
 272    {
 752273        Fixed64 num1 = rotation.X * 2;
 752274        Fixed64 num2 = rotation.Y * 2;
 752275        Fixed64 num3 = rotation.Z * 2;
 752276        Fixed64 num4 = rotation.X * num1;
 752277        Fixed64 num5 = rotation.Y * num2;
 752278        Fixed64 num6 = rotation.Z * num3;
 752279        Fixed64 num7 = rotation.X * num2;
 752280        Fixed64 num8 = rotation.X * num3;
 752281        Fixed64 num9 = rotation.Y * num3;
 752282        Fixed64 num10 = rotation.W * num1;
 752283        Fixed64 num11 = rotation.W * num2;
 752284        Fixed64 num12 = rotation.W * num3;
 285
 752286        Vector3d vector3 = new(
 752287            (Fixed64.One - (num5 + num6)) * point.X + (num7 - num12) * point.Y + (num8 + num11) * point.Z,
 752288            (num7 + num12) * point.X + (Fixed64.One - (num4 + num6)) * point.Y + (num9 - num10) * point.Z,
 752289            (num8 - num11) * point.X + (num9 + num10) * point.Y + (Fixed64.One - (num4 + num5)) * point.Z
 752290        );
 291
 752292        return vector3;
 293    }
 294
 295    /// <summary>
 296    /// Determines whether two Vector3d instances are equal.
 297    /// </summary>
 298    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 13523299    public static bool operator ==(Vector3d left, Vector3d right) => left.Equals(right);
 300
 301    /// <summary>
 302    /// Determines whether two Vector3d instances are not equal.
 303    /// </summary>
 304    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 612305    public static bool operator !=(Vector3d left, Vector3d right) => !left.Equals(right);
 306
 307    /// <summary>
 308    /// Determines whether each component of the left vector is greater than the corresponding component of the right
 309    /// vector.
 310    /// </summary>
 311    /// <param name="left">The first vector to compare.</param>
 312    /// <param name="right">The second vector to compare.</param>
 313    /// <returns>true if the x, y, and z components of left are all greater than those of right; otherwise, false.</retu
 314    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 315    public static bool operator >(Vector3d left, Vector3d right) =>
 4316        left.X > right.X
 4317        && left.Y > right.Y
 4318        && left.Z > right.Z;
 319
 320    /// <summary>
 321    /// Determines whether each component of the first Vector3d is less than the corresponding component of the second
 322    /// Vector3d.
 323    /// </summary>
 324    /// <remarks>
 325    /// This operator performs a component-wise comparison.
 326    /// All components of left must be less than the corresponding components of right for the result to be true.</remar
 327    /// <param name="left">The first Vector3d to compare.</param>
 328    /// <param name="right">The second Vector3d to compare.</param>
 329    /// <returns>true if the x, y, and z components of left are all less than those of right; otherwise, false.</returns
 330    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 331    public static bool operator <(Vector3d left, Vector3d right) =>
 4332        left.X < right.X
 4333        && left.Y < right.Y
 4334        && left.Z < right.Z;
 335
 336    /// <summary>
 337    /// Determines whether each component of the left Vector3d is greater than or equal to the corresponding component
 338    /// of the right Vector3d.
 339    /// </summary>
 340    /// <param name="left">The first Vector3d to compare.</param>
 341    /// <param name="right">The second Vector3d to compare.</param>
 342    /// <returns>true if the x, y, and z components of left are each greater than or equal to those of right; otherwise,
 343    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 344    public static bool operator >=(Vector3d left, Vector3d right) =>
 4345        left.X >= right.X
 4346        && left.Y >= right.Y
 4347        && left.Z >= right.Z;
 348
 349    /// <summary>
 350    /// Determines whether each component of the first Vector3d is less than or equal to the corresponding component of
 351    /// the second Vector3d.
 352    /// </summary>
 353    /// <param name="left">The first Vector3d to compare.</param>
 354    /// <param name="right">The second Vector3d to compare.</param>
 355    /// <returns>true if the x, y, and z components of left are each less than or equal to the corresponding components 
 356    /// otherwise, false.</returns>
 357    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 358    public static bool operator <=(Vector3d left, Vector3d right) =>
 4359        left.X <= right.X
 4360        && left.Y <= right.Y
 4361        && left.Z <= right.Z;
 362}

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

#LineLine coverage
 1//=======================================================================
 2// Vector3d.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 factory methods and arithmetic operations for <see cref="Vector3d"/>.
 16/// </content>
 17public partial struct Vector3d
 18{
 19    #region Static Operations
 20
 21    /// <summary>
 22    /// Adds two vectors component-wise.
 23    /// </summary>
 24    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 125    public static Vector3d Add(Vector3d v1, Vector3d v2) => v1 + v2;
 26
 27    /// <summary>
 28    /// Attempts to add two vectors without component saturation.
 29    /// </summary>
 30    /// <param name="left">The left operand.</param>
 31    /// <param name="right">The right operand.</param>
 32    /// <param name="result">
 33    /// The exact component-wise sum when every component is representable; otherwise, <see langword="default"/>.
 34    /// </param>
 35    /// <returns>
 36    /// <see langword="true"/> when every exact component is representable; otherwise, <see langword="false"/>.
 37    /// </returns>
 38    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 39    public static bool TryAdd(Vector3d left, Vector3d right, out Vector3d result)
 40    {
 21341        if (!Fixed64.TryAdd(left.X, right.X, out Fixed64 x)
 21342            || !Fixed64.TryAdd(left.Y, right.Y, out Fixed64 y)
 21343            || !Fixed64.TryAdd(left.Z, right.Z, out Fixed64 z))
 44        {
 1345            result = default;
 1346            return false;
 47        }
 48
 20049        result = new Vector3d(x, y, z);
 20050        return true;
 51    }
 52
 53    /// <summary>
 54    /// Subtracts two vectors component-wise.
 55    /// </summary>
 56    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 157    public static Vector3d Subtract(Vector3d v1, Vector3d v2) => v1 - v2;
 58
 59    /// <summary>
 60    /// Attempts to subtract two vectors without component saturation.
 61    /// </summary>
 62    /// <param name="left">The left operand.</param>
 63    /// <param name="right">The right operand.</param>
 64    /// <param name="result">
 65    /// The exact component-wise difference when every component is representable; otherwise, <see langword="default"/>.
 66    /// </param>
 67    /// <returns>
 68    /// <see langword="true"/> when every exact component is representable; otherwise, <see langword="false"/>.
 69    /// </returns>
 70    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 71    public static bool TrySubtract(Vector3d left, Vector3d right, out Vector3d result)
 72    {
 125973        if (!Fixed64.TrySubtract(left.X, right.X, out Fixed64 x)
 125974            || !Fixed64.TrySubtract(left.Y, right.Y, out Fixed64 y)
 125975            || !Fixed64.TrySubtract(left.Z, right.Z, out Fixed64 z))
 76        {
 677            result = default;
 678            return false;
 79        }
 80
 125381        result = new Vector3d(x, y, z);
 125382        return true;
 83    }
 84
 85    /// <summary>
 86    /// Attempts to add two vectors and subtract a third component-wise without intermediate saturation.
 87    /// </summary>
 88    /// <param name="firstAddend">The first addend.</param>
 89    /// <param name="secondAddend">The second addend.</param>
 90    /// <param name="subtrahend">The vector to subtract from the exact component-wise sum.</param>
 91    /// <param name="result">
 92    /// The exact component-wise result when every component is representable; otherwise, <see langword="default"/>.
 93    /// </param>
 94    /// <returns>
 95    /// <see langword="true"/> when every exact component is representable; otherwise, <see langword="false"/>.
 96    /// </returns>
 97    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 98    public static bool TryAddSubtract(
 99        Vector3d firstAddend,
 100        Vector3d secondAddend,
 101        Vector3d subtrahend,
 102        out Vector3d result)
 103    {
 140104        if (!Fixed64.TryAddSubtract(firstAddend.X, secondAddend.X, subtrahend.X, out Fixed64 x)
 140105            || !Fixed64.TryAddSubtract(firstAddend.Y, secondAddend.Y, subtrahend.Y, out Fixed64 y)
 140106            || !Fixed64.TryAddSubtract(firstAddend.Z, secondAddend.Z, subtrahend.Z, out Fixed64 z))
 107        {
 16108            result = default;
 16109            return false;
 110        }
 111
 124112        result = new Vector3d(x, y, z);
 124113        return true;
 114    }
 115
 116    /// <summary>
 117    /// Attempts to compute <c>(firstLeft + firstRight) -
 118    /// (secondLeft + secondRight)</c> component-wise without intermediate
 119    /// saturation.
 120    /// </summary>
 121    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 122    public static bool TrySubtractSums(
 123        Vector3d firstLeft,
 124        Vector3d firstRight,
 125        Vector3d secondLeft,
 126        Vector3d secondRight,
 127        out Vector3d result)
 128    {
 93129        bool representable = Fixed64.TrySubtractSums(
 93130                firstLeft.X,
 93131                firstRight.X,
 93132                secondLeft.X,
 93133                secondRight.X,
 93134                out Fixed64 x)
 93135            & Fixed64.TrySubtractSums(
 93136                firstLeft.Y,
 93137                firstRight.Y,
 93138                secondLeft.Y,
 93139                secondRight.Y,
 93140                out Fixed64 y)
 93141            & Fixed64.TrySubtractSums(
 93142                firstLeft.Z,
 93143                firstRight.Z,
 93144                secondLeft.Z,
 93145                secondRight.Z,
 93146                out Fixed64 z);
 93147        if (!representable)
 148        {
 2149            result = default;
 2150            return false;
 151        }
 152
 91153        result = new Vector3d(x, y, z);
 91154        return true;
 155    }
 156
 157    /// <summary>
 158    /// Attempts to calculate the cross product with one final
 159    /// round-half-to-even conversion per component.
 160    /// </summary>
 161    public static bool TryCross(
 162        Vector3d left,
 163        Vector3d right,
 164        out Vector3d result)
 165    {
 67166        bool representable = Fixed64.TrySubtractProducts(
 67167                left.Y,
 67168                right.Z,
 67169                left.Z,
 67170                right.Y,
 67171                out Fixed64 x)
 67172            & Fixed64.TrySubtractProducts(
 67173                left.Z,
 67174                right.X,
 67175                left.X,
 67176                right.Z,
 67177                out Fixed64 y)
 67178            & Fixed64.TrySubtractProducts(
 67179                left.X,
 67180                right.Y,
 67181                left.Y,
 67182                right.X,
 67183                out Fixed64 z);
 67184        if (!representable)
 185        {
 1186            result = default;
 1187            return false;
 188        }
 189
 66190        result = new Vector3d(x, y, z);
 66191        return true;
 192    }
 193
 194    /// <summary>
 195    /// Attempts to calculate the dot product with one final
 196    /// round-half-to-even conversion.
 197    /// </summary>
 198    public static bool TryDot(
 199        Vector3d left,
 200        Vector3d right,
 201        out Fixed64 result) =>
 67202        Fixed64.TryAddProducts(
 67203            left.X,
 67204            right.X,
 67205            left.Y,
 67206            right.Y,
 67207            left.Z,
 67208            right.Z,
 67209            out result);
 210
 211    /// <summary>
 212    /// Attempts to combine two scaled vectors with one final
 213    /// round-half-to-even conversion per component.
 214    /// </summary>
 215    public static bool TryLinearCombination(
 216        Vector3d first,
 217        Fixed64 firstScale,
 218        Vector3d second,
 219        Fixed64 secondScale,
 220        out Vector3d result)
 221    {
 2222        bool representable = Fixed64.TryAddProducts(
 2223                first.X,
 2224                firstScale,
 2225                second.X,
 2226                secondScale,
 2227                out Fixed64 x)
 2228            & Fixed64.TryAddProducts(
 2229                first.Y,
 2230                firstScale,
 2231                second.Y,
 2232                secondScale,
 2233                out Fixed64 y)
 2234            & Fixed64.TryAddProducts(
 2235                first.Z,
 2236                firstScale,
 2237                second.Z,
 2238                secondScale,
 2239                out Fixed64 z);
 2240        if (!representable)
 241        {
 1242            result = default;
 1243            return false;
 244        }
 245
 1246        result = new Vector3d(x, y, z);
 1247        return true;
 248    }
 249
 250    /// <summary>
 251    /// Attempts to combine three scaled vectors with one final
 252    /// round-half-to-even conversion per component.
 253    /// </summary>
 254    public static bool TryLinearCombination(
 255        Vector3d first,
 256        Fixed64 firstScale,
 257        Vector3d second,
 258        Fixed64 secondScale,
 259        Vector3d third,
 260        Fixed64 thirdScale,
 261        out Vector3d result)
 262    {
 67263        bool representable = Fixed64.TryAddProducts(
 67264                first.X,
 67265                firstScale,
 67266                second.X,
 67267                secondScale,
 67268                third.X,
 67269                thirdScale,
 67270                out Fixed64 x)
 67271            & Fixed64.TryAddProducts(
 67272                first.Y,
 67273                firstScale,
 67274                second.Y,
 67275                secondScale,
 67276                third.Y,
 67277                thirdScale,
 67278                out Fixed64 y)
 67279            & Fixed64.TryAddProducts(
 67280                first.Z,
 67281                firstScale,
 67282                second.Z,
 67283                secondScale,
 67284                third.Z,
 67285                thirdScale,
 67286                out Fixed64 z);
 67287        if (!representable)
 288        {
 1289            result = default;
 1290            return false;
 291        }
 292
 66293        result = new Vector3d(x, y, z);
 66294        return true;
 295    }
 296
 297    /// <summary>
 298    /// Attempts to combine three scaled vectors, apply a final scale, and
 299    /// round each completed component once.
 300    /// </summary>
 301    public static bool TryScaledLinearCombination(
 302        Vector3d first,
 303        Fixed64 firstScale,
 304        Vector3d second,
 305        Fixed64 secondScale,
 306        Vector3d third,
 307        Fixed64 thirdScale,
 308        Fixed64 resultScale,
 309        out Vector3d result)
 310    {
 4311        bool representable = Fixed64.TryAddScaledProducts(
 4312                first.X,
 4313                firstScale,
 4314                second.X,
 4315                secondScale,
 4316                third.X,
 4317                thirdScale,
 4318                resultScale,
 4319                out Fixed64 x)
 4320            & Fixed64.TryAddScaledProducts(
 4321                first.Y,
 4322                firstScale,
 4323                second.Y,
 4324                secondScale,
 4325                third.Y,
 4326                thirdScale,
 4327                resultScale,
 4328                out Fixed64 y)
 4329            & Fixed64.TryAddScaledProducts(
 4330                first.Z,
 4331                firstScale,
 4332                second.Z,
 4333                secondScale,
 4334                third.Z,
 4335                thirdScale,
 4336                resultScale,
 4337                out Fixed64 z);
 4338        if (!representable)
 339        {
 2340            result = default;
 2341            return false;
 342        }
 343
 2344        result = new Vector3d(x, y, z);
 2345        return true;
 346    }
 347
 348    /// <summary>
 349    /// Compares the exact component-difference projections of two vectors.
 350    /// </summary>
 351    /// <param name="candidate">The candidate point.</param>
 352    /// <param name="current">The point to compare against.</param>
 353    /// <param name="direction">The projection direction; it need not be normalized.</param>
 354    /// <returns>
 355    /// A negative value, zero, or a positive value when the candidate projection is
 356    /// respectively less than, equal to, or greater than the current projection.
 357    /// </returns>
 358    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 359    public static int CompareProjection(Vector3d candidate, Vector3d current, Vector3d direction) =>
 5360        WideGeometry.CompareDifferenceProjection(
 5361            candidate.X,
 5362            current.X,
 5363            direction.X,
 5364            candidate.Y,
 5365            current.Y,
 5366            direction.Y,
 5367            candidate.Z,
 5368            current.Z,
 5369            direction.Z);
 370
 371    /// <summary>
 372    /// Projects <paramref name="target"/> minus <paramref name="source"/> onto a direction
 373    /// without intermediate saturation, then returns a conservative nonnegative result.
 374    /// </summary>
 375    /// <param name="target">The target point.</param>
 376    /// <param name="source">The source point.</param>
 377    /// <param name="direction">The projection direction; it need not be normalized.</param>
 378    /// <returns>
 379    /// Zero for a nonpositive projection, the positive projection floored to Q32.32, or
 380    /// <see cref="Fixed64.MaxValue"/> when only the final result is unrepresentable.
 381    /// </returns>
 382    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 383    public static Fixed64 ProjectNonNegativeDifference(
 384        Vector3d target,
 385        Vector3d source,
 386        Vector3d direction) =>
 8387        Fixed64.ProjectNonNegativeDifference(
 8388            target.X,
 8389            source.X,
 8390            direction.X,
 8391            target.Y,
 8392            source.Y,
 8393            direction.Y,
 8394            target.Z,
 8395            source.Z,
 8396            direction.Z);
 397
 398    /// <summary>
 399    /// Projects <paramref name="target"/> minus <paramref name="source"/> onto
 400    /// <paramref name="direction"/> and returns the nonnegative parametric
 401    /// coordinate along that direction.
 402    /// </summary>
 403    /// <remarks>
 404    /// Unlike <see cref="ProjectNonNegativeDifference"/>, this method divides
 405    /// the exact dot product by the direction's exact squared length. The
 406    /// direction therefore need not have an exactly unit squared length.
 407    /// Zero and negative projections return zero; an unrepresentable positive
 408    /// parameter saturates to <see cref="Fixed64.MaxValue"/>.
 409    /// </remarks>
 410    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 411    public static Fixed64 ProjectNonNegativeDifferenceParameter(
 412        Vector3d target,
 413        Vector3d source,
 414        Vector3d direction) =>
 19415        WideGeometry.GetNonNegativeDifferenceProjectionParameter(target, source, direction);
 416
 417    /// <summary>
 418    /// Multiplies two vectors component-wise.
 419    /// </summary>
 420    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2421    public static Vector3d Multiply(Vector3d v1, Vector3d v2) => v1 * v2;
 422
 423    /// <summary>
 424    /// Multiplies each vector component by the specified scalar.
 425    /// </summary>
 426    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1427    public static Vector3d Multiply(Vector3d value, Fixed64 factor) => value * factor;
 428
 429    /// <summary>
 430    /// Divides each component of the first vector by the corresponding component of the second vector.
 431    /// </summary>
 432    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1433    public static Vector3d Divide(Vector3d v1, Vector3d v2) => v1 / v2;
 434
 435    /// <summary>
 436    /// Divides each vector component by the specified scalar.
 437    /// </summary>
 438    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1439    public static Vector3d Divide(Vector3d value, Fixed64 divisor) => value / divisor;
 440
 441    /// <summary>
 442    /// Linearly interpolates between two points.
 443    /// </summary>
 444    /// <param name="a">Start value, returned when t = 0.</param>
 445    /// <param name="b">End value, returned when t = 1.</param>
 446    /// <param name="mag">Value used to interpolate between a and b.</param>
 447    /// <returns> Interpolated value, equals to a + (b - a) * t.</returns>
 448    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 449    public static Vector3d Lerp(Vector3d a, Vector3d b, Fixed64 mag)
 450    {
 489451        mag = FixedMath.Clamp01(mag);
 489452        return new Vector3d(
 489453            FixedMath.Lerp(a.X, b.X, mag),
 489454            FixedMath.Lerp(a.Y, b.Y, mag),
 489455            FixedMath.Lerp(a.Z, b.Z, mag));
 456    }
 457
 458    /// <summary>
 459    /// Linearly interpolates between two vectors without clamping the interpolation factor between 0 and 1.
 460    /// </summary>
 461    /// <param name="a">The start vector.</param>
 462    /// <param name="b">The end vector.</param>
 463    /// <param name="t">The interpolation factor. Values outside the range [0, 1] will cause the interpolation to go bey
 464    /// <returns>The interpolated vector.</returns>
 465    /// <remarks>
 466    /// Unlike traditional Lerp, this function allows interpolation factors greater than 1 or less than 0,
 467    /// which means the resulting vector can extend beyond the endpoints.
 468    /// </remarks>
 4469    public static Vector3d UnclampedLerp(Vector3d a, Vector3d b, Fixed64 t) => (b - a) * t + a;
 470
 471    /// <summary>
 472    /// Moves from a to b at some speed dependent of a delta time with out passing b.
 473    /// </summary>
 474    /// <param name="a"></param>
 475    /// <param name="b"></param>
 476    /// <param name="speed"></param>
 477    /// <param name="dt"></param>
 478    /// <returns></returns>
 479    public static Vector3d SpeedLerp(Vector3d a, Vector3d b, Fixed64 speed, Fixed64 dt)
 480    {
 3481        Vector3d v = b - a;
 3482        Fixed64 dv = speed * dt;
 3483        return dv > v.Magnitude
 3484            ? b
 3485            : a + v.Normalized * dv;
 486    }
 487
 488    /// <summary>
 489    /// Spherically interpolates between two vectors, moving along the shortest arc on a unit sphere.
 490    /// </summary>
 491    /// <param name="start">The starting vector.</param>
 492    /// <param name="end">The ending vector.</param>
 493    /// <param name="percent">A value between 0 and 1 that represents the interpolation amount. 0 returns the start vect
 494    /// <returns>The interpolated vector between the two input vectors.</returns>
 495    /// <remarks>
 496    /// Slerp is used to interpolate between two unit vectors on a sphere, providing smooth rotation.
 497    /// It can be more computationally expensive than linear interpolation (Lerp) but results in smoother, arc-like moti
 498    /// </remarks>
 499    public static Vector3d Slerp(Vector3d start, Vector3d end, Fixed64 percent)
 500    {
 501        // Dot product - the cosine of the angle between 2 vectors.
 6502        Fixed64 dot = Dot(start, end);
 503        // Clamp it to be in the range of Acos()
 504        // This may be unnecessary, but floating point
 505        // precision can be a fickle mistress.
 6506        dot = FixedMath.Clamp(dot, -Fixed64.One, Fixed64.One);
 507        // Acos(dot) returns the angle between start and end,
 508        // And multiplying that by percent returns the angle between
 509        // start and the final result.
 6510        Fixed64 theta = FixedMath.Acos(dot) * percent;
 6511        Vector3d RelativeVec = end - start * dot;
 6512        RelativeVec.NormalizeInPlace();
 513        // Orthonormal basis
 514        // The final result.
 6515        return (start * FixedMath.Cos(theta)) + (RelativeVec * FixedMath.Sin(theta));
 516    }
 517
 518    /// <summary>
 519    /// Calculates a position between four points using Catmull-Rom interpolation.
 520    /// </summary>
 521    /// <param name="value1">The first point.</param>
 522    /// <param name="value2">The second point.</param>
 523    /// <param name="value3">The third point.</param>
 524    /// <param name="value4">The fourth point.</param>
 525    /// <param name="amount">The interpolation factor.</param>
 526    /// <returns>The interpolated position.</returns>
 527    public static Vector3d CatmullRom(
 528        Vector3d value1,
 529        Vector3d value2,
 530        Vector3d value3,
 531        Vector3d value4,
 532        Fixed64 amount)
 533    {
 1534        return new Vector3d(
 1535            FixedMath.CatmullRom(value1.X, value2.X, value3.X, value4.X, amount),
 1536            FixedMath.CatmullRom(value1.Y, value2.Y, value3.Y, value4.Y, amount),
 1537            FixedMath.CatmullRom(value1.Z, value2.Z, value3.Z, value4.Z, amount)
 1538        );
 539    }
 540
 541    /// <summary>
 542    /// Calculates a position between two points using Hermite spline interpolation,
 543    /// which takes into account the tangents at the endpoints for smoother transitions.
 544    /// </summary>
 545    /// <param name="value1">The first point.</param>
 546    /// <param name="tangent1">The tangent at the first point.</param>
 547    /// <param name="value2">The second point.</param>
 548    /// <param name="tangent2">The tangent at the second point.</param>
 549    /// <param name="amount">The interpolation factor.</param>
 550    /// <returns>The interpolated position.</returns>
 551    public static Vector3d HermiteSpline(
 552        Vector3d value1,
 553        Vector3d tangent1,
 554        Vector3d value2,
 555        Vector3d tangent2,
 556        Fixed64 amount)
 557    {
 1558        return new Vector3d(
 1559            FixedMath.HermiteSpline(value1.X, tangent1.X, value2.X, tangent2.X, amount),
 1560            FixedMath.HermiteSpline(value1.Y, tangent1.Y, value2.Y, tangent2.Y, amount),
 1561            FixedMath.HermiteSpline(value1.Z, tangent1.Z, value2.Z, tangent2.Z, amount));
 562    }
 563
 564    /// <summary>
 565    /// Calculates a position between two points using a cubic Hermite interpolation,
 566    /// which is similar to HermiteSpline but assumes zero tangents at the endpoints for a smoother curve.
 567    /// </summary>
 568    /// <param name="value1">The first point.</param>
 569    /// <param name="value2">The second point.</param>
 570    /// <param name="amount">The interpolation factor.</param>
 571    /// <returns>The interpolated position.</returns>
 572    public static Vector3d SmoothStep(Vector3d value1, Vector3d value2, Fixed64 amount)
 573    {
 1574        return new Vector3d(
 1575            FixedMath.SmoothStep(value1.X, value2.X, amount),
 1576            FixedMath.SmoothStep(value1.Y, value2.Y, amount),
 1577            FixedMath.SmoothStep(value1.Z, value2.Z, amount)
 1578        );
 579    }
 580
 581    /// <summary>
 582    /// Normalizes the given vector, returning a unit vector with the same direction.
 583    /// </summary>
 584    /// <param name="value">The vector to normalize.</param>
 585    /// <returns>A normalized (unit) vector with the same direction.</returns>
 586    public static Vector3d GetNormalized(Vector3d value)
 587    {
 246588        bool magnitudeIsRepresentable = TryGetMagnitude(
 246589            value,
 246590            out Fixed64 mag,
 246591            out bool isNormalized);
 592
 593        // If magnitude is zero, return a zero vector to avoid divide-by-zero errors
 246594        if (mag == Fixed64.Zero)
 1595            return new Vector3d(Fixed64.Zero, Fixed64.Zero, Fixed64.Zero);
 596
 245597        if (isNormalized)
 123598            return value;
 599
 122600        if (!magnitudeIsRepresentable || mag == Fixed64.One)
 6601            return WideNormalization.GetNormalized(value);
 602
 116603        if (mag <= FixedMath.ScaleSafeMagnitudeThreshold)
 9604            return GetScaleNormalized(value);
 605
 107606        var normalized = new Vector3d(
 107607            FixedMath.FastDiv(value.X, mag),
 107608            FixedMath.FastDiv(value.Y, mag),
 107609            FixedMath.FastDiv(value.Z, mag));
 107610        return normalized.IsNormalized()
 107611            ? normalized
 107612            : WideNormalization.GetNormalized(value);
 613    }
 614
 615    internal static Vector3d GetScaleNormalized(Vector3d value)
 616    {
 8442617        Fixed64 scale = FixedMath.Max(value.X.Abs(), FixedMath.Max(value.Y.Abs(), value.Z.Abs()));
 8442618        Vector3d scaled = value / scale;
 8442619        Fixed64 scaledMagnitude = FixedMath.GetScaledMagnitude(
 8442620            scaled.X,
 8442621            scaled.Y,
 8442622            scaled.Z,
 8442623            Fixed64.Zero);
 8442624        return scaled / scaledMagnitude;
 625    }
 626
 627    /// <summary>
 628    /// Attempts to compose two component-scaled offsets in a shared frame and
 629    /// one rotated inner-frame displacement with one final round-half-to-even
 630    /// conversion per component.
 631    /// </summary>
 632    /// <remarks>
 633    /// Computes
 634    /// <c>outerScale * outerLocalPoint
 635    /// + innerFrameScale * innerFrameOffset
 636    /// + Rotate(innerLocalDisplacement)</c>
 637    /// without narrowing either scaled offset or the rotated displacement
 638    /// independently.
 639    /// </remarks>
 640    public static bool TryComposeScaledLocalPoints(
 641        Vector3d outerLocalPoint,
 642        Vector3d outerScale,
 643        Vector3d innerFrameOffset,
 644        Vector3d innerFrameScale,
 645        Vector3d innerLocalDisplacement,
 646        FixedQuaternion innerRotation,
 647        out Vector3d result) =>
 67648        WideVector3dTransform.TryComposeScaledLocalPoints(
 67649            outerLocalPoint,
 67650            outerScale,
 67651            innerFrameOffset,
 67652            innerFrameScale,
 67653            innerLocalDisplacement,
 67654            innerRotation,
 67655            out result);
 656
 657    /// <summary>
 658    /// Returns the normalized direction from <paramref name="start"/> toward
 659    /// <paramref name="end"/> across the complete coordinate domain.
 660    /// </summary>
 661    /// <remarks>
 662    /// Equal endpoints return <see cref="Zero"/>. Endpoint differences are
 663    /// evaluated exactly even when a component cannot be represented by
 664    /// <see cref="Fixed64"/>.
 665    /// </remarks>
 666    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 667    public static Vector3d GetDirection(Vector3d start, Vector3d end) =>
 4668        WideNormalization.GetDirection(start, end);
 669
 670    /// <summary>
 671    /// Returns the magnitude (length) of this vector.
 672    /// </summary>
 673    /// <param name="vector">The vector whose magnitude is being calculated.</param>
 674    /// <returns>The magnitude of the vector.</returns>
 675    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 676    public static Fixed64 GetMagnitude(Vector3d vector)
 677    {
 14180678        _ = TryGetMagnitude(vector, out Fixed64 magnitude);
 14180679        return magnitude;
 680    }
 681
 682    /// <summary>
 683    /// Attempts to return the magnitude of the given vector without saturating the result.
 684    /// </summary>
 685    /// <param name="vector">The vector to measure.</param>
 686    /// <param name="magnitude">The magnitude, or <see cref="Fixed64.MaxValue"/> when it is not representable.</param>
 687    /// <returns><see langword="true"/> when the magnitude fits in <see cref="Fixed64"/>; otherwise, <see langword="fals
 688    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 689    public static bool TryGetMagnitude(Vector3d vector, out Fixed64 magnitude) =>
 14558690        TryGetMagnitude(vector, out magnitude, out _);
 691
 692    private static bool TryGetMagnitude(
 693        Vector3d vector,
 694        out Fixed64 magnitude,
 695        out bool isNormalized)
 696    {
 14819697        Fixed64 mag = (vector.X * vector.X) + (vector.Y * vector.Y) + (vector.Z * vector.Z);
 14819698        isNormalized = mag != Fixed64.Zero
 14819699            && FixedMath.Abs(mag - Fixed64.One) <= Fixed64.Epsilon;
 700
 14819701        if (mag == Fixed64.MaxValue)
 45702            return FixedMath.TryGetScaledMagnitude(
 45703                vector.X,
 45704                vector.Y,
 45705                vector.Z,
 45706                Fixed64.Zero,
 45707                out magnitude);
 708
 14774709        if (mag <= FixedMath.ScaleSafeMagnitudeSquaredThreshold)
 710        {
 73711            magnitude = FixedMath.GetScaledMagnitude(
 73712                vector.X,
 73713                vector.Y,
 73714                vector.Z,
 73715                Fixed64.Zero);
 73716            return true;
 717        }
 718
 14701719        if (isNormalized)
 720        {
 14125721            magnitude = Fixed64.One;
 14125722            return true;
 723        }
 724
 576725        magnitude = FixedMath.Sqrt(mag);
 576726        return true;
 727    }
 728
 729    /// <summary>
 730    /// Attempts to return the distance between two endpoints without saturating
 731    /// any component difference.
 732    /// </summary>
 733    /// <param name="start">The first endpoint.</param>
 734    /// <param name="end">The second endpoint.</param>
 735    /// <param name="distance">The rounded distance, or <see cref="Fixed64.MaxValue"/> when it is not representable.</pa
 736    /// <returns><see langword="true"/> when the distance fits in <see cref="Fixed64"/>; otherwise, <see langword="false
 737    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 738    public static bool TryGetDistance(Vector3d start, Vector3d end, out Fixed64 distance) =>
 24739        WideGeometry.TryGetDistance(start, end, out distance);
 740
 741    /// <summary>
 742    /// Compares the exact squared magnitudes of two vectors without fixed-point saturation.
 743    /// </summary>
 744    /// <returns>A negative value when <paramref name="left"/> is shorter, zero when the
 745    /// magnitudes are equal, or a positive value when <paramref name="left"/> is longer.</returns>
 746    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 747    public static int CompareMagnitudeSquared(Vector3d left, Vector3d right) =>
 3748        Fixed64.CompareMagnitudeSquared(
 3749            left.X,
 3750            left.Y,
 3751            left.Z,
 3752            Fixed64.Zero,
 3753            right.X,
 3754            right.Y,
 3755            right.Z,
 3756            Fixed64.Zero);
 757
 758    /// <summary>
 759    /// Compares the exact squared distances between two pairs of points without fixed-point saturation.
 760    /// </summary>
 761    /// <returns>A negative value when the left distance is shorter, zero when the
 762    /// distances are equal, or a positive value when the left distance is longer.</returns>
 763    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 764    public static int CompareDistanceSquared(
 765        Vector3d leftStart,
 766        Vector3d leftEnd,
 767        Vector3d rightStart,
 768        Vector3d rightEnd) =>
 72769        WideGeometry.CompareSquaredDistance3D(
 72770            leftStart.X, leftEnd.X,
 72771            leftStart.Y, leftEnd.Y,
 72772            leftStart.Z, leftEnd.Z,
 72773            rightStart.X, rightEnd.X,
 72774            rightStart.Y, rightEnd.Y,
 72775            rightStart.Z, rightEnd.Z);
 776
 777    /// <summary>
 778    /// Returns the exact sign of the scalar triple product without fixed-point saturation.
 779    /// </summary>
 780    /// <returns><c>1</c> for a positive product, <c>-1</c> for a negative product,
 781    /// or <c>0</c> when the vectors are exactly coplanar.</returns>
 782    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 783    public static int ScalarTripleProductSign(Vector3d first, Vector3d second, Vector3d third) =>
 3784        WideGeometry.GetTripleProductSign(
 3785            first.X, first.Y, first.Z,
 3786            second.X, second.Y, second.Z,
 3787            third.X, third.Y, third.Z);
 788
 789    /// <summary>
 790    /// Returns a new <see cref="Vector3d"/> where each component is the absolute value of the corresponding input compo
 791    /// </summary>
 792    /// <param name="value">The input vector.</param>
 793    /// <returns>A vector with absolute values for each component.</returns>
 794    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1795    public static Vector3d Abs(Vector3d value) => new(value.X.Abs(), value.Y.Abs(), value.Z.Abs());
 796
 797    /// <summary>
 798    /// Returns a new <see cref="Vector3d"/> where each component is the sign of the corresponding input component.
 799    /// </summary>
 800    /// <param name="value">The input vector.</param>
 801    /// <returns>A vector where each component is -1, 0, or 1 based on the sign of the input.</returns>
 802    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1803    public static Vector3d Sign(Vector3d value) => new(value.X.Sign(), value.Y.Sign(), value.Z.Sign());
 804
 805    /// <summary>
 806    /// Attempts to calculate the exact non-negative weighted average with one
 807    /// final round-half-to-even conversion per component.
 808    /// </summary>
 809    /// <remarks>
 810    /// Zero-weight values are ignored. The operation returns
 811    /// <see langword="false"/> only when the total weight is zero.
 812    /// </remarks>
 813    public static bool TryGetWeightedAverage(
 814        ReadOnlySpan<Vector3d> values,
 815        ReadOnlySpan<Fixed64> weights,
 816        out Vector3d average)
 817    {
 179818        WideWeightedAverage.ValidateInputs(values.Length, weights);
 177819        return WideWeightedAverage.TryGet(values, weights, out average);
 820    }
 821
 822    /// <summary>
 823    /// Clamps each component of the given <see cref="Vector3d"/> within the specified min and max bounds.
 824    /// </summary>
 825    /// <param name="value">The vector to clamp.</param>
 826    /// <param name="min">The minimum bounds.</param>
 827    /// <param name="max">The maximum bounds.</param>
 828    /// <returns>A vector with each component clamped between min and max.</returns>
 829    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 830    public static Vector3d Clamp(Vector3d value, Vector3d min, Vector3d max) =>
 5831        new(FixedMath.Clamp(value.X, min.X, max.X),
 5832            FixedMath.Clamp(value.Y, min.Y, max.Y),
 5833            FixedMath.Clamp(value.Z, min.Z, max.Z));
 834
 835    /// <summary>
 836    /// Clamps the given Vector3d within the specified magnitude.
 837    /// </summary>
 838    /// <param name="value"></param>
 839    /// <param name="maxMagnitude"></param>
 840    /// <returns></returns>
 841    public static Vector3d ClampMagnitude(Vector3d value, Fixed64 maxMagnitude)
 842    {
 2843        if (value.MagnitudeSquared > maxMagnitude * maxMagnitude)
 1844            return value.Normalized * maxMagnitude; // Clamp magnitude without changing direction
 845
 1846        return value;
 847    }
 848
 849    /// <summary>
 850    /// Determines if two vectors are exactly parallel by checking if their cross product is zero.
 851    /// </summary>
 852    /// <param name="v1">The first vector.</param>
 853    /// <param name="v2">The second vector.</param>
 854    /// <returns>True if the vectors are exactly parallel, false otherwise.</returns>
 2855    public static bool AreParallel(Vector3d v1, Vector3d v2) => Cross(v1, v2).MagnitudeSquared == Fixed64.Zero;
 856
 857    /// <summary>
 858    /// Determines if two vectors are approximately parallel based on a cosine similarity threshold.
 859    /// </summary>
 860    /// <param name="v1">The first normalized vector.</param>
 861    /// <param name="v2">The second normalized vector.</param>
 862    /// <param name="cosThreshold">The cosine similarity threshold for near-parallel vectors.</param>
 863    /// <returns>True if the vectors are nearly parallel, false otherwise.</returns>
 864    public static bool AreAlmostParallel(Vector3d v1, Vector3d v2, Fixed64 cosThreshold)
 865    {
 866        // Assuming v1 and v2 are already normalized
 2867        Fixed64 dot = Dot(v1, v2);
 868
 869        // Compare dot product directly to the cosine threshold
 2870        return dot >= cosThreshold;
 871    }
 872
 873    /// <summary>
 874    /// Computes the midpoint between two vectors.
 875    /// </summary>
 876    /// <param name="v1">The first vector.</param>
 877    /// <param name="v2">The second vector.</param>
 878    /// <returns>The midpoint vector.</returns>
 879    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 880    public static Vector3d Midpoint(Vector3d v1, Vector3d v2) =>
 57881        new(FixedMath.Midpoint(v1.X, v2.X), FixedMath.Midpoint(v1.Y, v2.Y), FixedMath.Midpoint(v1.Z, v2.Z));
 882
 883    /// <inheritdoc cref="Distance(Fixed64, Fixed64, Fixed64)" />
 884    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 36885    public static Fixed64 Distance(Vector3d start, Vector3d end) => start.Distance(end.X, end.Y, end.Z);
 886
 887    /// <inheritdoc cref="DistanceSquared(Fixed64, Fixed64, Fixed64)" />
 888    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 100889    public static Fixed64 DistanceSquared(Vector3d start, Vector3d end) => start.DistanceSquared(end.X, end.Y, end.Z);
 890
 891    /// <summary>
 892    /// Calculates the closest point on a line segment defined by start and end points to a given point in space.
 893    /// </summary>
 894    /// <param name="point">The point to project onto the segment.</param>
 895    /// <param name="start">The start of the line segment.</param>
 896    /// <param name="end">The end of the line segment.</param>
 897    /// <returns>The closest point on the line segment to the given point.</returns>
 898    /// <remarks>
 899    /// Endpoint differences and projection products are evaluated across the
 900    /// complete raw domain before the parameter is clamped and rounded.
 901    /// A direction whose exact Q64.64 squared-length total is at most 2^31 raw
 902    /// units rounds to zero in Q32.32 and returns <paramref name="start"/>.
 903    /// </remarks>
 904    public static Vector3d ClosestPointOnLineSegment(Vector3d point, Vector3d start, Vector3d end)
 905    {
 143906        Signed192 denominator = WideGeometry.GetDifferenceDotProduct3D(
 143907            end.X, start.X, end.Y, start.Y, end.Z, start.Z,
 143908            end.X, start.X, end.Y, start.Y, end.Z, start.Z);
 143909        if (WideGeometry.IsSquaredLengthDegenerate(denominator))
 37910            return start;
 911
 106912        Signed192 numerator = WideGeometry.GetDifferenceDotProduct3D(
 106913            point.X, start.X, point.Y, start.Y, point.Z, start.Z,
 106914            end.X, start.X, end.Y, start.Y, end.Z, start.Z);
 106915        if (numerator.Sign <= 0)
 20916            return start;
 86917        if (WideArithmetic.CompareMagnitude(numerator, denominator) >= 0)
 29918            return end;
 919
 57920        _ = Fixed64.TryGetUnitIntervalRatio(numerator, denominator, out Fixed64 parameter);
 57921        return new Vector3d(
 57922            FixedMath.Lerp(start.X, end.X, parameter),
 57923            FixedMath.Lerp(start.Y, end.Y, parameter),
 57924            FixedMath.Lerp(start.Z, end.Z, parameter));
 925    }
 926
 927    /// <summary>
 928    /// Dot Product of two vectors.
 929    /// </summary>
 930    /// <param name="lhs"></param>
 931    /// <param name="rhs"></param>
 932    /// <returns></returns>
 933    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 32658934    public static Fixed64 Dot(Vector3d lhs, Vector3d rhs) => lhs.Dot(rhs.X, rhs.Y, rhs.Z);
 935
 936    /// <summary>
 937    /// Cross Product of two vectors.
 938    /// </summary>
 939    /// <param name="lhs"></param>
 940    /// <param name="rhs"></param>
 941    /// <returns></returns>
 942    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 6208943    public static Vector3d Cross(Vector3d lhs, Vector3d rhs) => lhs.Cross(rhs.X, rhs.Y, rhs.Z);
 944
 945    /// <inheritdoc cref="CrossProduct(Fixed64, Fixed64, Fixed64)"/>
 946    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 4947    public static Fixed64 CrossProduct(Vector3d lhs, Vector3d rhs) => lhs.CrossProduct(rhs.X, rhs.Y, rhs.Z);
 948
 949    /// <summary>
 950    /// Projects a vector onto another vector.
 951    /// </summary>
 952    /// <param name="vector"></param>
 953    /// <param name="onNormal"></param>
 954    /// <returns></returns>
 955    public static Vector3d Project(Vector3d vector, Vector3d onNormal)
 956    {
 5957        Fixed64 sqrMag = Dot(onNormal, onNormal);
 5958        if (sqrMag.Abs() < Fixed64.Epsilon)
 1959            return Zero;
 960        else
 961        {
 4962            Fixed64 dot = Dot(vector, onNormal);
 4963            return new Vector3d(onNormal.X * dot / sqrMag,
 4964                onNormal.Y * dot / sqrMag,
 4965                onNormal.Z * dot / sqrMag);
 966        }
 967    }
 968
 969    /// <summary>
 970    /// Projects a vector onto a plane defined by a normal orthogonal to the plane.
 971    /// </summary>
 972    /// <param name="vector"></param>
 973    /// <param name="planeNormal"></param>
 974    /// <returns></returns>
 975    public static Vector3d ProjectOnPlane(Vector3d vector, Vector3d planeNormal)
 976    {
 4977        Fixed64 sqrMag = Dot(planeNormal, planeNormal);
 4978        if (sqrMag.Abs() < Fixed64.Epsilon)
 1979            return vector;
 980        else
 981        {
 3982            Fixed64 dot = Dot(vector, planeNormal);
 3983            return new Vector3d(vector.X - planeNormal.X * dot / sqrMag,
 3984                vector.Y - planeNormal.Y * dot / sqrMag,
 3985                vector.Z - planeNormal.Z * dot / sqrMag);
 986        }
 987    }
 988
 989    /// <summary>
 990    /// Returns the normalized direction of a vector projected onto a plane.
 991    /// </summary>
 992    /// <remarks>
 993    /// The rejection is formed exactly with full-domain intermediates before
 994    /// returning its nearest representable normalized direction. A zero normal
 995    /// returns the normalized input vector; a zero projection returns
 996    /// <see cref="Zero"/>.
 997    /// </remarks>
 998    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 999    public static Vector3d GetNormalizedProjectionOnPlane(
 1000        Vector3d vector,
 1001        Vector3d planeNormal) =>
 51002        Geometry.WideGeometry.GetNormalizedProjectionOnPlane(vector, planeNormal);
 1003
 1004    /// <summary>
 1005    /// Projects a point onto a plane defined by a normal and a distance from the origin.
 1006    /// </summary>
 1007    /// <param name="point">The point to project.</param>
 1008    /// <param name="plane">The plane onto which the point is projected.</param>
 1009    /// <returns>The projected point.</returns>
 1010    public static Vector3d ProjectOnPlane(Vector3d point, FixedPlane plane)
 1011    {
 281012        Fixed64 normalLengthSquared = plane.Normal.MagnitudeSquared;
 281013        if (normalLengthSquared == Fixed64.Zero)
 11014            return point;
 1015
 271016        Fixed64 distance = plane.DotCoordinate(point);
 271017        return point - plane.Normal * FixedMath.FastDiv(distance, normalLengthSquared);
 1018    }
 1019
 1020    /// <summary>
 1021    /// Computes the angle in degrees between two vectors.
 1022    /// </summary>
 1023    /// <param name="from">The starting vector.</param>
 1024    /// <param name="to">The target vector.</param>
 1025    /// <returns>The angle in degrees between the two vectors.</returns>
 1026    /// <remarks>
 1027    /// This method calculates the angle by using the dot product between the vectors and normalizing the result.
 1028    /// The angle is always the smaller angle between the two vectors on a plane.
 1029    /// </remarks>
 1030    public static Fixed64 Angle(Vector3d from, Vector3d to)
 1031    {
 41032        Fixed64 denominator = FixedMath.Sqrt(from.MagnitudeSquared * to.MagnitudeSquared);
 1033
 41034        if (denominator.Abs() < Fixed64.Epsilon)
 11035            return Fixed64.Zero;
 1036
 31037        Fixed64 dot = FixedMath.Clamp(Dot(from, to) / denominator, -Fixed64.One, Fixed64.One);
 1038
 31039        return FixedMath.RadToDeg(FixedMath.Acos(dot));
 1040    }
 1041
 1042    /// <summary>
 1043    /// Calculates the barycentric coordinates of a point with respect to a triangle defined by three vertices.
 1044    /// </summary>
 1045    /// <param name="coordA">The first vertex of the triangle.</param>
 1046    /// <param name="coordB">The second vertex of the triangle.</param>
 1047    /// <param name="coordC">The third vertex of the triangle.</param>
 1048    /// <param name="weightB">The barycentric weight for the second vertex.</param>
 1049    /// <param name="weightC">The barycentric weight for the third vertex.</param>
 1050    /// <returns>The cartesian translation represented by the barycentric coordinates within the triangle.</returns>
 1051    public static Vector3d BarycentricCoordinates(
 1052        Vector3d coordA,
 1053        Vector3d coordB,
 1054        Vector3d coordC,
 1055        Fixed64 weightB,
 1056        Fixed64 weightC)
 1057    {
 1151058        return new(
 1151059            FixedMath.BarycentricCoordinate(coordA.X, coordB.X, coordC.X, weightB, weightC),
 1151060            FixedMath.BarycentricCoordinate(coordA.Y, coordB.Y, coordC.Y, weightB, weightC),
 1151061            FixedMath.BarycentricCoordinate(coordA.Z, coordB.Z, coordC.Z, weightB, weightC));
 1062    }
 1063
 1064    /// <summary>
 1065    ///  Returns a vector whose elements are the maximum of each of the pairs of elements in two specified vectors.
 1066    /// </summary>
 1067    /// <param name="value1">The first vector.</param>
 1068    /// <param name="value2">The second vector.</param>
 1069    /// <returns>The maximized vector.</returns>
 1070    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1071    public static Vector3d Max(Vector3d value1, Vector3d value2) =>
 14611072         new(FixedMath.Max(value1.X, value2.X),
 14611073             FixedMath.Max(value1.Y, value2.Y),
 14611074             FixedMath.Max(value1.Z, value2.Z));
 1075
 1076    /// <summary>
 1077    /// Returns a vector whose elements are the minimum of each of the pairs of elements in two specified vectors.
 1078    /// </summary>
 1079    /// <param name="value1">The first vector.</param>
 1080    /// <param name="value2">The second vector.</param>
 1081    /// <returns>The minimized vector.</returns>
 1082    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1083    public static Vector3d Min(Vector3d value1, Vector3d value2) =>
 14611084        new(FixedMath.Min(value1.X, value2.X),
 14611085            FixedMath.Min(value1.Y, value2.Y),
 14611086            FixedMath.Min(value1.Z, value2.Z));
 1087
 1088    /// <summary>
 1089    /// Returns a vector that is the negation of the specified vector, effectively reversing its direction.
 1090    /// </summary>
 1091    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 11092    public static Vector3d Negate(Vector3d value) => -value;
 1093
 1094    /// <summary>
 1095    /// Rotates the vector around a given position using a specified quaternion rotation.
 1096    /// </summary>
 1097    /// <param name="source">The vector to rotate.</param>
 1098    /// <param name="position">The position around which the vector is rotated.</param>
 1099    /// <param name="rotation">The quaternion representing the rotation.</param>
 1100    /// <returns>The rotated vector.</returns>
 1101    public static Vector3d Rotate(Vector3d source, Vector3d position, FixedQuaternion rotation)
 1102    {
 11103        source -= position; // Translate the vector by the position
 11104        var normalizedRotation = rotation.Normalized;
 11105        return (normalizedRotation * source) + position;
 1106    }
 1107
 1108    /// <summary>
 1109    /// Applies the inverse of a specified quaternion rotation to the vector around a given position.
 1110    /// </summary>
 1111    /// <param name="source">The vector to rotate.</param>
 1112    /// <param name="position">The position around which the vector is rotated.</param>
 1113    /// <param name="rotation">The quaternion representing the inverse rotation.</param>
 1114    /// <returns>The rotated vector.</returns>
 1115    public static Vector3d InverseRotate(Vector3d source, Vector3d position, FixedQuaternion rotation)
 1116    {
 11117        source -= position; // Translate the vector by the position
 11118        var normalizedRotation = rotation.Normalized;
 1119        // Undo the rotation
 11120        source = normalizedRotation.Inverse() * source;
 1121        // Add the original position back
 11122        return source + position;
 1123    }
 1124
 1125    /// <summary>
 1126    /// Reflects a vector off the plane defined by a normal.
 1127    /// The result is a vector that points in the direction a perfectly reflected ray would go,
 1128    /// based on the incoming vector and the normal of the plane it reflects off.
 1129    /// </summary>
 1130    /// <param name="vector">The vector to reflect.</param>
 1131    /// <param name="normal">The normal of the plane to reflect off.</param>
 1132    /// <returns>The reflected vector.</returns>
 1133    public static Vector3d Reflect(Vector3d vector, Vector3d normal)
 1134    {
 21135        Fixed64 dot = Dot(vector, normal);
 21136        return vector - 2 * dot * normal;
 1137    }
 1138
 1139    /// <summary>
 1140    /// Transforms a vector by the given 4x4 matrix, applying rotation, scaling, and translation as defined by the matri
 1141    /// </summary>
 1142    /// <param name="vector">The vector to transform.</param>
 1143    /// <param name="matrix">The transformation matrix.</param>
 1144    /// <returns>The transformed vector.</returns>
 1145    /// <remarks>
 1146    /// Same as <see cref="operator *(Vector3d, Fixed4x4)"/>.
 1147    /// </remarks>
 21148    public static Vector3d Transform(Vector3d vector, Fixed4x4 matrix) => matrix * vector;
 1149
 1150    #endregion
 1151}

Methods/Properties

ToString()
ToString(System.String,System.IFormatProvider)
TryFormat(System.Span`1<System.Char>,System.Int32&,System.ReadOnlySpan`1<System.Char>,System.IFormatProvider)
ToVector2d()
ToVector4d(FixedMathSharp.Fixed64)
Deconstruct(FixedMathSharp.Fixed64&,FixedMathSharp.Fixed64&,FixedMathSharp.Fixed64&)
Deconstruct(System.Int32&,System.Int32&,System.Int32&)
Deconstruct(System.Int64&,System.Int64&,System.Int64&)
Deconstruct(System.Double&,System.Double&,System.Double&)
ToDegrees(FixedMathSharp.Vector3d)
ToRadians(FixedMathSharp.Vector3d)
get_Up()
get_Right()
get_Down()
get_Left()
get_Forward()
get_Backward()
get_One()
get_Negative()
get_Zero()
.ctor(System.Int32,System.Int32,System.Int32)
.ctor(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
FromDouble(System.Double,System.Double,System.Double)
get_RightHandNormal()
get_LeftHandNormal()
get_Normalized()
get_Magnitude()
get_MagnitudeSquared()
get_Direction()
get_IsZero()
get_LongStateHash()
get_StateHash()
get_Item(System.Int32)
set_Item(System.Int32,FixedMathSharp.Fixed64)
Set(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
AddInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
AddInPlace(FixedMathSharp.Fixed64)
AddInPlace(FixedMathSharp.Vector3d)
SubtractInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
SubtractInPlace(FixedMathSharp.Fixed64)
SubtractInPlace(FixedMathSharp.Vector3d)
MultiplyInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
MultiplyInPlace(FixedMathSharp.Fixed64)
MultiplyInPlace(FixedMathSharp.Vector3d)
DivideInPlace(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
DivideInPlace(FixedMathSharp.Fixed64)
DivideInPlace(FixedMathSharp.Vector3d)
NormalizeInPlace()
NormalizeInPlace(FixedMathSharp.Fixed64&)
IsNormalized()
TryGetMagnitudeCeiling(FixedMathSharp.Fixed64&)
AllComponentsGreaterThanEpsilon()
SnapSmallComponentsToZero(System.Nullable`1<FixedMathSharp.Fixed64>)
Distance(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
DistanceSquared(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Dot(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
CrossProduct(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Cross(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Equals(System.Object)
Equals(FixedMathSharp.Vector3d)
Equals(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
GetHashCode()
GetHashCode(FixedMathSharp.Vector3d)
CompareTo(FixedMathSharp.Vector3d)
op_Addition(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
op_Addition(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
op_Addition(FixedMathSharp.Fixed64,FixedMathSharp.Vector3d)
op_Addition(FixedMathSharp.Vector3d,System.ValueTuple`3<System.Int32,System.Int32,System.Int32>)
op_Addition(System.ValueTuple`3<System.Int32,System.Int32,System.Int32>,FixedMathSharp.Vector3d)
op_Subtraction(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
op_Subtraction(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
op_Subtraction(FixedMathSharp.Vector3d,System.ValueTuple`3<System.Int32,System.Int32,System.Int32>)
op_Subtraction(System.ValueTuple`3<System.Int32,System.Int32,System.Int32>,FixedMathSharp.Vector3d)
op_UnaryNegation(FixedMathSharp.Vector3d)
op_Multiply(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
op_Multiply(FixedMathSharp.Fixed64,FixedMathSharp.Vector3d)
op_Multiply(FixedMathSharp.Vector3d,System.Int32)
op_Multiply(System.Int32,FixedMathSharp.Vector3d)
op_Multiply(FixedMathSharp.Fixed3x3,FixedMathSharp.Vector3d)
op_Multiply(FixedMathSharp.Vector3d,FixedMathSharp.Fixed3x3)
op_Multiply(FixedMathSharp.Fixed4x4,FixedMathSharp.Vector3d)
op_Multiply(FixedMathSharp.Vector3d,FixedMathSharp.Fixed4x4)
op_Multiply(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
op_Division(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
op_Division(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
op_Division(FixedMathSharp.Vector3d,System.Int32)
op_Multiply(FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion)
op_Multiply(FixedMathSharp.FixedQuaternion,FixedMathSharp.Vector3d)
op_Equality(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
op_Inequality(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
op_GreaterThan(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
op_LessThan(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
op_GreaterThanOrEqual(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
op_LessThanOrEqual(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Add(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
TryAdd(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d&)
Subtract(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
TrySubtract(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d&)
TryAddSubtract(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d&)
TrySubtractSums(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d&)
TryCross(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d&)
TryDot(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64&)
TryLinearCombination(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d&)
TryLinearCombination(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d&)
TryScaledLinearCombination(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d&)
CompareProjection(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
ProjectNonNegativeDifference(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
ProjectNonNegativeDifferenceParameter(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Multiply(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Multiply(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
Divide(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Divide(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
Lerp(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
UnclampedLerp(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
SpeedLerp(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Slerp(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
CatmullRom(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
HermiteSpline(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
SmoothStep(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
GetNormalized(FixedMathSharp.Vector3d)
GetScaleNormalized(FixedMathSharp.Vector3d)
TryComposeScaledLocalPoints(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion,FixedMathSharp.Vector3d&)
GetDirection(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
GetMagnitude(FixedMathSharp.Vector3d)
TryGetMagnitude(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64&)
TryGetMagnitude(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64&,System.Boolean&)
TryGetDistance(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64&)
CompareMagnitudeSquared(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
CompareDistanceSquared(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
ScalarTripleProductSign(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Abs(FixedMathSharp.Vector3d)
Sign(FixedMathSharp.Vector3d)
TryGetWeightedAverage(System.ReadOnlySpan`1<FixedMathSharp.Vector3d>,System.ReadOnlySpan`1<FixedMathSharp.Fixed64>,FixedMathSharp.Vector3d&)
Clamp(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
ClampMagnitude(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
AreParallel(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
AreAlmostParallel(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
Midpoint(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Distance(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
DistanceSquared(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
ClosestPointOnLineSegment(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Dot(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Cross(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
CrossProduct(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Project(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
ProjectOnPlane(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
GetNormalizedProjectionOnPlane(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
ProjectOnPlane(FixedMathSharp.Vector3d,FixedMathSharp.Geometry.FixedPlane)
Angle(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
BarycentricCoordinates(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
Max(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Min(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Negate(FixedMathSharp.Vector3d)
Rotate(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion)
InverseRotate(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.FixedQuaternion)
Reflect(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
Transform(FixedMathSharp.Vector3d,FixedMathSharp.Fixed4x4)