Skip to content

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 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 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 static method defined which negates the bits of the vector components. (BitwiseComplement?)
  • 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 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 IBinaryFloatingPointIeee754<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 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.
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