Skip to content

[3.0] Generic Matrix Math#2528

Draft
otac0n wants to merge 108 commits intodotnet:develop/3.0from
otac0n:feature/math-3.0
Draft

[3.0] Generic Matrix Math#2528
otac0n wants to merge 108 commits intodotnet:develop/3.0from
otac0n:feature/math-3.0

Conversation

@otac0n
Copy link
Contributor

@otac0n otac0n commented Jan 2, 2026

This PR is a continuation of #2459 and supersedes it.

Status snapshot:

Vector structs:

  • Implements IEquatable with itself as the generic parameter
  • Implements IReadOnlyList with the components as the list elements
  • Implements ISpanFormattable
  • Implements ISpanParsable
  • Implements IUtf8SpanFormattable
  • Implements IUtf8SpanParsable
  • Implements IParsable
  • Implemetns IFormattable
  • The relevant number of properties to represent the mathematical vector's components (X and Y for Vector2) and relevant unit vectors
  • Constructors which take either a single parameter and uses it for every component, a parameter for each component, or a ReadOnlySpan of values which has the same number of elements as our vector has components.
  • Constructors for 3 dimensions and up must include lower dimension variants that use the lower dimensions for their specific components (vector2 -> X,Y).
  • A ref indexer that takes a int index and returns the corresponding component value (0 -> x, 1 -> y, etc.)
  • An AsSpan function which returns this vector as a Span of the generic type
  • A LengthSquared extension property which returns the dot product of the vector with itself.
  • A Length extension property which returns the magnitued of the vector when the type T defines IRootFunctions<T>.
  • A Dot static method which takes another vector and returns the dot product with our original vector.
  • For 3D Vectors, a Cross static method which takes another vector and returns the cross product with our original vector.
  • +, -, *, /, and % operators defined between two vectors of the same type which returns a vector which has had each operation applied component-wise.
  • +, -, *, /, and % operators defined between a vector and a scalar value that matches the generic type which returns a vector which has had each operation applied component-wise with the scalar value. Both vector first and scalar first should be implemented.
  • A - unary operator which returns the negated vector.
  • A + unary operator which returns the vector.
  • Overrides ToString to show component values.
  • CopyTo functions which copy to an array or span, with or without a starting index
  • Explicit cast and checked cast operators to all builtin type parameter variants of the vector types of the same dimensionality. (e.g. from Vector2D<T> to Vector2D<float>)
  • Explicit cast and checked cast to and from matching System.Numerics vector type
  • Explicit cast cast to lower dimensional matching vector with matching generic type
  • Static Unit Vectors for each component
  • A Static Zero Vector with zero for all components
  • A Static One Vector with one for all components
  • A static AllBitsSet Vector with all bits set for all components
  • A deconstruct method for detupling
  • An implicit conversion from a value tuple of the same size.
  • Define static CreateChecked, CreateSaturating, and CreateTruncating which converts other vector types to this type
    • Try variants of these methods should also be defined which out the resulting vector and return a bool representing success or failure of the operation.
  • Define Transform static methods which take a Matrix of higher dimensionality assuming 1 in for the final missing component and 0 for the rest (Vector 2 can use Matrix2Xn, Matrix3Xn, and Matrix4Xn) and return a vector containing the output (type should match the outer type e.g. Vector2D.Transform(Matrix4X4) returns Vector2D)
  • Define VectorND<T> * MatrixNXM operators where N is the same for both Vector and Matrix, but M is any number
    • These operators should function like Transform, but without needed assumptions
  • Define TransformNormal static methods which take a Matrix of higher dimensionality assuming 0 in for all missing components (Vector 2 can use Matrix2Xn, Matrix3Xn, and Matrix4Xn) and return a vector containing the output (type should match the outer type e.g. Vector2D.Transform(Matrix4X4) returns Vector2D)
  • For types implementing IBinaryNumber
    • BitwiseAnd, BitwiseOr, and BitwiseXor ExclusiveOr static methods defined between two vectors which returns a vector which has had these operators applied on a component-wise basis.
    • BitwiseAnd, BitwiseOr, and BitwiseXor ExclusiveOr static methods operators defined between a vectors and a scalar value that matches the generic type which returns a vector which has had these operators applied on a component-wise basis with the scalar.
    • BitwiseNot OnesComplement static method defined which negates the bits of the vector components.
  • A Normalize extension method which divides all components by the length of the vector, when T implements IRootFunctions<T>
  • A Reflect static method which takes a normal vector and reflects the vector over the normal
  • The following static Vector properties which have the given value for all components
    • PositiveInfinity
    • NegativeInfinity
    • NaN
    • Epsilon
    • NegativeZero
    • Pi
    • Tau
    • E
  • Define the following static methods for these types which calls the specified function and returns a new vector with the specified multiplicity:
    • INumber<>.Sign, (Memberwise)
      • Returns VectorND<int>, where N matches the dimensionality of the vector
    • INumber<>.Max, (Memberwise, Memberwise)
    • INumber<>.Max, (Memberwise, Scalar)
    • INumber<>.MaxNumber, (Memberwise, Memberwise)
    • INumber<>.MaxNumber, (Memberwise, Scalar)
    • INumber<>.Min, (Memberwise, Memberwise)
    • INumber<>.Min, (Memberwise, Scalar)
    • INumber<>.MinNumber, (Memberwise, Memberwise)
    • INumber<>.MinNumber, (Memberwise, Scalar)
    • INumber<>.Clamp, (Memberwise, Memberwise, Memberwise)
    • INumber<>.Clamp, (Memberwise, Scalar, Scalar)
    • INumber<>.CopySign, (Memberwise, Memberwise)
    • INumber<>.CopySign, (Memberwise, Scalar)
    • INumberBase<>.Abs, (Memberwise)
    • INumberBase<>.MaxMagnitude, (Memberwise, Memberwise)
    • INumberBase<>.MaxMagnitudeNumber, (Memberwise, Memberwise)
    • INumberBase<>.MinMagnitude, (Memberwise, Memberwise)
    • INumberBase<>.MinMagnitudeNumber, (Memberwise, Memberwise)
    • INumberBase<>.MultiplyAddEstimate, (Memberwise, Memberwise, Memberwise)
    • INumberBase<>.MultiplyAddEstimate, (Memberwise, Memberwise, Scalar)
    • INumberBase<>.MultiplyAddEstimate, (Memberwise, Scalar, Memberwise)
    • INumberBase<>.MultiplyAddEstimate, (Memberwise, Scalar, Scalar)
    • Log2, (Memberwise)
    • IBinaryInteger<>.DivRem, (Memberwise)
      • Returns tuple of 2 Vectors (Vector Quotient, Vector Remainder)
    • IBinaryInteger<>.PopCount, (Memberwise)
    • IBinaryInteger<>.TrailingZeroCount, (Memberwise)
    • IFloatingPoint<>.Ceiling, (Memberwise)
    • IFloatingPoint<>.Floor, (Memberwise)
    • IFloatingPoint<>.Round, (Memberwise)
    • IFloatingPoint<>.Round, (Memberwise, Scalar) *int digits
    • IFloatingPoint<>.Round, (Memberwise, Scalar) *MidpointRounding mode
    • IFloatingPoint<>.Round, (Memberwise, Scalar, Scalar) *int digits, MidpointRounding mode
    • IFloatingPoint<>.Truncate, (Memberwise)
    • IFloatingPointIeee754<>.Atan2, (Memberwise, Memberwise)
    • IFloatingPointIeee754<>.Atan2Pi, (Memberwise, Memberwise)
    • IFloatingPointIeee754<>.Lerp, (Memberwise, Memberwise, Memberwise)
    • IFloatingPointIeee754<>.Lerp, (Memberwise, Memberwise, Scalar)
    • IFloatingPointIeee754<>.BitDecrement, (Memberwise)
    • IFloatingPointIeee754<>.BitIncrement, (Memberwise)
    • IFloatingPointIeee754<>.FusedMultiplyAdd, (Memberwise, Memberwise, Memberwise)
    • IFloatingPointIeee754<>.FusedMultiplyAdd, (Memberwise, Memberwise, Scalar)
    • IFloatingPointIeee754<>.FusedMultiplyAdd, (Memberwise, Scalar, Memberwise)
    • IFloatingPointIeee754<>.FusedMultiplyAdd, (Memberwise, Scalar, Scalar)
    • IFloatingPointIeee754<>.Ieee754Remainder, (Memberwise, Memberwise)
    • IFloatingPointIeee754<>.Ieee754Remainder, (Memberwise, Scalar)
    • IFloatingPointIeee754<>.ILogB, (Memberwise)
      • Returns VectorND<int>, where N matches the dimensionality of the vector
    • IFloatingPointIeee754<>.ReciprocalEstimate, (Memberwise)
    • IFloatingPointIeee754<>.ReciprocalSqrtEstimate, (Memberwise)
    • IFloatingPointIeee754<>.ScaleB, (Memberwise, Memberwise)
    • IFloatingPointIeee754<>.ScaleB, (Memberwise, Scalar)
    • IPowerFunctions<>.Pow, (Memberwise, Memberwise)
    • IPowerFunctions<>.Pow, (Memberwise, Scalar)
    • IRootFunctions<>.Cbrt, (Memberwise)
    • IRootFunctions<>.Sqrt, (Memberwise)
    • IRootFunctions<>.RootN, (Memberwise, Memberwise)
    • IRootFunctions<>.RootN, (Memberwise, Scalar)
    • IRootFunctions<>.Hypot, (Memberwise, Memberwise)
    • IRootFunctions<>.Hypot, (Memberwise, Scalar)
    • ILogarithmicFunctions<>.Log, (Memberwise)
    • ILogarithmicFunctions<>.Log, (Memberwise, Memberwise)
    • ILogarithmicFunctions<>.Log, (Memberwise, Scalar)
    • ILogarithmicFunctions<>.LogP1, (Memberwise)
    • ILogarithmicFunctions<>.Log2P1, (Memberwise)
    • ILogarithmicFunctions<>.Log10, (Memberwise)
    • ILogarithmicFunctions<>.Log10P1, (Memberwise)
    • IExponentialFunctions<>.Exp, (Memberwise)
    • IExponentialFunctions<>.ExpM1, (Memberwise)
    • IExponentialFunctions<>.Exp2, (Memberwise)
    • IExponentialFunctions<>.Exp2M1, (Memberwise)
    • IExponentialFunctions<>.Exp10, (Memberwise)
    • IExponentialFunctions<>.Exp10M1, (Memberwise)
    • ITrigonometricFunctions<>.Acos, (Memberwise)
    • ITrigonometricFunctions<>.AcosPi, (Memberwise)
    • ITrigonometricFunctions<>.Asin, (Memberwise)
    • ITrigonometricFunctions<>.AsinPi, (Memberwise)
    • ITrigonometricFunctions<>.Atan, (Memberwise)
    • ITrigonometricFunctions<>.AtanPi, (Memberwise)
    • ITrigonometricFunctions<>.Cos, (Memberwise)
    • ITrigonometricFunctions<>.CosPi, (Memberwise)
    • ITrigonometricFunctions<>.Sin, (Memberwise)
    • ITrigonometricFunctions<>.SinPi, (Memberwise)
    • ITrigonometricFunctions<>.SinCos, (Memberwise)
      • Returns a tuple of 2 Vectors (Sin, Cos)
    • ITrigonometricFunctions<>.SinCosPi, (Memberwise)
      • Returns a tuple of 2 Vectors (Sin, Cos)
    • ITrigonometricFunctions<>.Tan, (Memberwise)
    • ITrigonometricFunctions<>.TanPi, (Memberwise)
    • ITrigonometricFunctions<>.DegreesToRadians, (Memberwise)
    • ITrigonometricFunctions<>.RadiansToDegrees, (Memberwise)
    • IHyperbolicFunctions<>.Acosh, (Memberwise)
    • IHyperbolicFunctions<>.Asinh, (Memberwise)
    • IHyperbolicFunctions<>.Atanh, (Memberwise)
    • IHyperbolicFunctions<>.Cosh, (Memberwise)
    • IHyperbolicFunctions<>.Sinh, (Memberwise)
    • IHyperbolicFunctions<>.Tanh, (Memberwise)
    • RoundToInt(Vector x)
      • Returns VectorND<int>, where N matches the dimensionality of the vector
      • INFORMATIVE This may require multiple methods depending on implementation
    • FloorToInt(Vector x)
      • Returns VectorND<int>, where N matches the dimensionality of the vector
      • INFORMATIVE This may require multiple methods depending on implementation
    • CeilingToInt(Vector x)
      • Returns VectorND<int>, where N matches the dimensionality of the vector
      • INFORMATIVE This may require multiple methods depending on implementation
    • ToVector64(Vector x)
      • Returns System.Runtime.Intrinsics.Vector64<TScalar>
    • ToVector128(Vector x)
      • Returns System.Runtime.Intrinsics.Vector128<TScalar>
    • ToVector256(Vector x)
      • Returns System.Runtime.Intrinsics.Vector256<TScalar>
    • ToVector512(Vector x)
      • Returns System.Runtime.Intrinsics.Vector512<TScalar>

Matrix structs must fulfill the following requirements:

  • Fulfills IEquatable<T> where T is the same matrix class
  • Stored in row major format
  • Both row vectors and individual values (M11, etc.) accessible via properties
  • A ref indexer that takes row and column indicies and outputs the value
  • Add, subtract, and multiply operators defined with Matricies of the same size
  • Multiply operators defined with compatible matricies, if the output matrix type already exists (AxB * BxC = AxC)
  • Negate Operator defined
  • Implicit Explicit conversion to and from the System.Numerics matrix type, if available
  • Invert extension method for square matricies
  • GetDeterminant extension method for square matricies and Matrix3X2, Matrix4X3, and Matrix5X4
  • Transpose extension method
  • Lerp static method
  • static identity property for square matrices
  • For Matrix3X2, Matrix3X3, Matrix4X3, and Matrix4X4 include the following static functions
    • CreateBillboardRH
    • CreateBillboardLH
    • CreateRotation
      • 3x3, 4x3, and 4x4 Matricies get X, Y, and Z variants for this function instead
    • CreateTranslation
    • CreateScale
    • Decompose (separate out any transformations)
  • For Matrix3X2 include a CreateSkew static function
  • For Matrix3X3, Matrix4X3, and Matrix4X4 include the following static functions
    • CreateFromAxisAngle
    • CreateFromQuaternion
    • Transform
      • from a Quaternion
    • CreateFromYawPitchRoll
  • For Matrix4X3 and Matrix4X4 include the following static functions
    • CreateConstrainedBillboardLH
    • CreateConstrainedBillboardRH
    • CreateLookAtLH
    • CreateLookToLH
    • CreateOrthographicLH
    • CreateOrthographicOffCenterLH
    • CreatePerspectiveLH
    • CreatePerspectiveFieldOfViewLH
    • CreatePerspectiveOffCenterLH
    • CreateLookAtRH
    • CreateLookToRH
    • CreateOrthographicRH
    • CreateOrthographicOffCenterRH
    • CreatePerspectiveRH
    • CreatePerspectiveFieldOfViewRH
    • CreatePerspectiveOffCenterRH
    • CreateReflection
    • CreateWorld
    • CreateViewport

Several of these functions exist, but not for all types or not for both LH/RH versions.

A Quaternion struct:

  • A generic struct with a type parameter T which is constrained by INumber<T>, IRootFunctions<T>, ITrigonometricFunctions<T> representing the scalar type
  • Implements IEquatable with itself
  • Contain 4 scalar properties (X, Y, Z, W)
  • Define a Constructor taking 4 scalar values matching the properties
  • Define a Constructor taking a Vector3D<T> and a Scalar, with the vector 3 mapping to X, Y, Z and the Scalar to the W
  • Define a Constructor taking a Vector4D<T>
  • A Vector3D<T> Axis property mapping to (X, Y, Z)
  • A T Angle property mapping to 2 * Acos(W)
  • A ref Indexer which takes an int and returns the components in order
  • An AsSpan function which returns this quaternion as a Span of the generic type
  • An IsIdentity property which returns if this Quaternion matches an Identity Quaternion
  • Define +, -, *, and / between two Quaternions
  • Define * with T multiplying each component by the scalar value returning a new quaternion
  • Define unary ~
  • A Dot function which takes another Quaternion and returns its the dotproduct between them
    • A static implementation of this function must be available
  • A LengthSquared property which returns the dot product of the quaternion with itself
  • A Length property which returns the Square Root of LengthSquared
  • An Invert function inverts the Quaternion
    • a static Inverse Invert function must be available but it returns the inverse rather than affecting the original
  • A Normalize function which normalizes the Quaternion
    • A static implemenation of this function must be available but returns the normalized Quaternion rather than affecting the original
  • A Concatenate function which takes another Quaternion and concatenates it with this quaternion
    • A static implementation of this function must be available but it returns a new Quaternion rather than affecting the originals
  • A Conjugate function which returns the conjugate of this quaternion
    • A static implementation of this function must be available
  • A static CreateFromAxisAngle function which takes in a Vector3D<T> and an angle and returns a Quaternion representing that rotation
  • A static CreateFromRotationMatrix function which takes either a Matrix3X3 or Matrix4X4 and returns a Quaternion representing that rotation
  • A static CreateFromYawPitchRoll which takes either each components separately or in a Vector3D<T> and outputs a Quaternion representing that rotation
  • A static Lerp function which takes 2 Quaternions and a Scalar matching the generic type which linearly interpolates between the 2 Quaternions with scalar used as the amount to lerp
  • A static SLerp function which takes 2 Quaternions and a Scalar matching the generic type which Spherical linearly interpolates between the 2 Quaternions with scalar used as the amount to lerp
  • A static Zero Quaternion Property
  • A static Identity Quaternion Property

Geometric Types:

  • Box2
  • Box3
  • Circle
  • Cube
  • Plane
  • Ray2
  • Ray3
  • Rectangle
  • Sphere

Geometric Types details:

  • Intersect functions with both another instance of the type and a point
  • GetDistanceToNearest(Point,Edge,etc) functions must be available for a given point
  • For all but the rays and planes, GetInflated function that takes a point and returns the scaled object that is closest to the original and contains the given point
  • Include Scale and Translation transformation functions
  • For Box and Rectangle the following Vector properties must be defined
    • Min
    • Max
    • Center
    • Size
  • For Planes and Rays, Normalize functions
  • For Planes include the following static functions
    • CreateFromVerticies
    • CreateFromPointNormal
    • Dot
      • with a Vector4
    • DotCoordinate and DotNormal
      • with a Vector3
    • Transform
      • With a Matrix4X4 or Quaternion, if relevant

Tweety-Lab and others added 30 commits May 28, 2025 19:10
More complete matrix implementation.
@otac0n
Copy link
Contributor Author

otac0n commented Feb 12, 2026

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants