i guess what i noticed in the standard library is names get shorter the lower-level you go? like it’s UInt32 not UnsignedInteger32
,, also, idk if this is helpful but I went through the vector.swift files in my projects to find my most used vector functionality and this is what I came up with:
enum Math<N>
{
typealias V2 = (x:N, y:N)
typealias V3 = (x:N, y:N, z:N)
typealias V4 = (x:N, y:N, z:N, w:N)
typealias Mat3 = (V3, V3, V3)
typealias Mat4 = (V4, V4, V4, V4)
static
func copy(_ v:V2, to pointer:UnsafeMutablePointer<N>)
static
func copy(_ v:V3, to pointer:UnsafeMutablePointer<N>)
static
func copy(_ v:V4, to pointer:UnsafeMutablePointer<N>)
static
func copy(_ v:Mat4, to pointer:UnsafeMutablePointer<N>)
static
func load(from pointer:UnsafeMutablePointer<N>) -> V2
static
func load(from pointer:UnsafeMutablePointer<N>) -> V3
static
func load(from pointer:UnsafeMutablePointer<N>) -> V4
}
extension Math where N:Numeric
{
static
func sum(_ v:V2) -> N
static
func sum(_ v:V3) -> N
static
func add(_ v1:V2, _ v2:V2) -> V2
static
func add(_ v1:V3, _ v2:V3) -> V3
static
func sub(_ v1:V2, _ v2:V2) -> V2
static
func sub(_ v1:V3, _ v2:V3) -> V3
static
func vol(_ v:V2) -> N // { return v.x * v.y }
static
func vol(_ v:V3) -> N // { return v.x * v.y * v.z }
static
func mult(_ v1:V2, _ v2:V2) -> V2
static
func mult(_ v1:V3, _ v2:V3) -> V3
static
func scale(_ v:V2, by c:N) -> V2
static
func scale(_ v:V3, by c:N) -> V3
static
func dot(_ v1:V2, _ v2:V2) -> N
static
func dot(_ v1:V3, _ v2:V3) -> N
static
func dot(_ v1:V4, _ v2:V4) -> N
static
func eusq(_ v:V2) -> N // { return v.x * v.x + v.y * v.y }
static
func eusq(_ v:V3) -> N // { return v.x * v.x + v.y * v.y + v.z * v.z }
static
func cross(_ v1:V2, _ v2:V2) -> N
static
func cross(_ v1:V3, _ v2:V3) -> V3
static
func mat3(from M:Mat4) -> Mat3
static
func transpose(_ M:Mat3) -> Mat3
static
func transpose(_ M:Mat4) -> Mat4
static
func mult(_ A:Mat3, _ v:V3) -> V3
static
func mult(_ A:Mat3, _ B:Mat3) -> Mat3
static
func mult(_ A:Mat4, _ v:V4) -> V4
static
func mult(_ A:Mat4, _ B:Mat4) -> Mat4
static
func homogenize(_ v:V2) -> V3 // { return (v.x, v.y, 1) }
static
func homogenize(_ v:V3) -> V4
}
extension Math where N:Numeric, N:Comparable
{
// compares magnitudes without doing .squareRoot()
static
func test(_ v:V2, lessThan r:N) -> Bool
static
func test(_ v:V3, lessThan r:N) -> Bool
static
func test(_ v:V2, lessEqual r:N) -> Bool
static
func test(_ v:V3, lessEqual r:N) -> Bool
}
extension Math where N:SignedNumeric
{
static
func neg(_ v:V2) -> V2 // { return (-v.x, -v.y) }
static
func neg(_ v:V3) -> V3
}
extension Math where N:FloatingPoint
{
static
func abs(_ v:V2) -> V2
static
func abs(_ v:V3) -> V3
// another day: we should add this to scalar types too...
static
func clamp(_ v:N, to range:ClosedRange<N> = 0 ... 1) -> N
static
func clamp(_ v:V2) -> V2
static
func clamp(_ v:V3) -> V3
}
extension Math where N:SignedNumeric, N.Magnitude == N
{
static
func abs(_ v:V2) -> V2
static
func abs(_ v:V3) -> V3
}
extension Math where N:Comparable, N:SignedNumeric
{
static
func abs(_ v:V2) -> V2
static
func abs(_ v:V3) -> V3
}
extension Math where N:BinaryFloatingPoint
{
static
func cast<I>(_ v:V2, as _:I.Type) -> Math<I>.V2 where I:BinaryInteger
static
func cast<I>(_ v:V3, as _:I.Type) -> Math<I>.V3 where I:BinaryInteger
}
extension Math where N:BinaryInteger
{
static
func cast<I>(_ v:V2, as _:I.Type) -> Math<I>.V2 where I:BinaryInteger
static
func cast<I>(_ v:V3, as _:I.Type) -> Math<I>.V3 where I:BinaryInteger
static
func cast<F>(_ v:V2, as _:F.Type) -> Math<F>.V2 where F:FloatingPoint
static
func cast<F>(_ v:V3, as _:F.Type) -> Math<F>.V3 where F:FloatingPoint
static
func idiv(_ dividend:V2, by divisor:V2) -> Math<(N, N)>.V2
static
func idiv(_ dividend:V3, by divisor:V3) -> Math<(N, N)>.V3
}
extension Math where N:FloatingPoint
{
static
func reciprocal(_ v:V2) -> V2
static
func reciprocal(_ v:V3) -> V3
static
func div(_ v1:V2, _ v2:V2) -> V2
static
func div(_ v1:V3, _ v2:V3) -> V3
static
func madd(_ v1:V2, _ v2:V2, _ v3:V2) -> V2
static
func madd(_ v1:V3, _ v2:V3, _ v3:V3) -> V3
static
func scadd(_ v1:V2, _ v2:V2, _ c:N) -> V2
static
func scadd(_ v1:V3, _ v2:V3, _ c:N) -> V3
// another thing that would be useful on scalar types too
static
func lerp(_ v1:N, _ v2:N, _ t:N) -> N
static
func lerp(_ v1:V2, _ v2:V2, _ t:N) -> V2
static
func lerp(_ v1:V3, _ v2:V3, _ t:N) -> V3
static
func length(_ v:V2) -> N
static
func length(_ v:V3) -> N
static
func normalize(_ v:V2) -> V2
static
func normalize(_ v:V3) -> V3
}
extension Math where N:BinaryFloatingPoint
{
static
func cast<F>(_ v:V2, as _:F.Type) -> Math<F>.V2 where F:BinaryFloatingPoint
static
func cast<F>(_ v:V3, as _:F.Type) -> Math<F>.V3 where F:BinaryFloatingPoint
}
extension Array
{
mutating
func append(vector:Math<Element>.V2)
mutating
func append(vector:Math<Element>.V3)
}
obviously the spelling is gonna be different depending on what people like (how do we feel about static methods?) but these are the operations i’ve found very useful when using vectors up to M = 4