This project is part of the @thi.ng/umbrella monorepo.
- About
- Installation
- Dependencies
- Usage examples
- API
- Breaking changes in v3.0.0
- Naming conventions
- Constants
- Component setters & copying
- Component swizzling
- Vector creation
- Basic vector math
- Multiply-add
- Constraints
- Cross product
- Dot product
- Interpolation
- Normalization / magnitude
- Distances
- Orientation
- Rotations
- Polar / cartesian conversion
- Randomness
- Unary vector math ops
- Vector array batch processing
- Comparison / equality
- Bitwise operations (int / uint vec)
- Boolean vector logic
- Componentwise comparisons
- Hashing
- Code generator
- Authors
- License
Likely the most comprehensive vector library for TypeScript / JavaScript currently available.
This package provides 600+ largely code generated functions and supporting types to perform vector operations on fixed and arbitrary-length vectors, both packed and strided (i.e. where individual vector components are not successive array elements, for example in SOA memory layouts).
Includes componentwise logic operations for boolean vectors, componentwise comparisons for numeric vectors and componentwise binary ops for signed & unsigned integer vectors.
- Small & fast: The vast majority of functions are code generated with fixed-sized versions not using any loops. Minified + gzipped, the entire package is ~9.2KB.
- Unified API: Any
ArrayLike
type can be used as vector containers (e.g. JS arrays, typed arrays, custom impls). Most functions are implemented as multi-methods, dispatching to any potentially optimized versions based on given vector arguments. - Highly modular: Each function is defined in its own submodule / file.
In addition to each generic multi-method base function, all
fixed-length optimized versions are exported too. E.g. If
add
performs vector addition on arbitrary-length vectors,add2
,add3
,add4
are the optimized version for fixed-length vectors... - Extensible: Custom vector ops can be defined in a similar manner using the provided code generation helpers (see vop.ts and codegen.ts for details).
- Immutable by default: Each operation producing a vector result takes
an output vector as first argument. If
null
, the vector given as 2nd argument will be used as output (i.e. for mutation). - Strided vector support is handled via the lightweight
Vec2/3/4
class wrappers and thegvec()
proxy (for generic, arbitrary-length vectors). These types behave like normal arrays (for read/write operations) and are also iterable. A subset of functions (suffixed withS
, e.g.addS
vs.add
) also support striding without the need for extra class wrappers. This is handled via additional index and stride arguments for each input/output vector. These functions are only available for sizes 2 / 3 / 4, though. - Random vector functions support the
IRandom
interface defined by @thi.ng/random to work with custom (P)RNGs. If omitted, the built-inMath.random()
will be used.
- @thi.ng/color - vector based color operations / conversions
- @thi.ng/geom - 2D/3D geometry types & operations
- @thi.ng/matrices - 2x2, 2x3, 3x3, 4x4 matrix & quaternion ops
- @thi.ng/shader-ast
- @thi.ng/vector-pools - operations on memory mapped data
yarn add @thi.ng/vectors
- @thi.ng/api
- @thi.ng/checks
- @thi.ng/equiv
- @thi.ng/errors
- @thi.ng/math
- @thi.ng/random
- @thi.ng/transducers
import * as v from "@thi.ng/vectors";
// immutable vector addition (1st arg is result)
v.add([], [1, 2, 3, 4], [10, 20, 30, 40]);
// [11, 22, 33, 44]
// mutable addition (if first arg is null)
a = [1, 2, 3];
v.add(null, a, a);
// [2, 4, 6]
// multiply-add (o = a * b + c)
v.madd([], [10, 20], [0.5, 0.25], [1, 2]);
// [6, 7]
// multiply-add w/ scalar (o = a * n + b)
v.maddN([], [10, 20], 0.5, [1, 2]);
// [6, 12]
// scalar addition w/ arbitrary length & strided vector
v.addN([], gvec([0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0], 3, 1, 4), 10);
// [11, 12, 13]
v.dist([1, 2], [100, 200]);
// 221.37072977247917
v.distManhattan([1, 2], [100, 200]);
// 297
v.distChebyshev([1, 2], [100, 200]);
// 198
v.mixN([], [1, 2], [10, 20], 0.5);
// [5.5, 11]
v.fromHomogeneous([], [100, 200, 0.5]);
// [200, 400]
v.swizzle4([], [1, 2], 1, 1, 0, 0);
// [ 2, 2, 1, 1 ]
v.hash([1, 2, 3])
// 2383338936
- to avoid confusion, the arg order of
madd
andmaddN
functions has been updated to be compatible with the OpenCLmad
functionmadd([], a, b, c)
: beforea + b * c
, now:a * b + c
maddN([], a, b, n)
=>maddN([], a, n, b)
(i.e.a * n + b
)
- rename
perpendicularLeft2
=>perpendicularCCW
- rename
perpendicularRight2
=>perpendicularCW
- rename
normalLeft2
/normalRight2
=>normalCCW
/normalCW
Wherever possible, each operation comes in different variations. All fixed size versions use optimized, loop-free implementations.
Suffix | Description | Example |
---|---|---|
none | arbitrary length vector arg(s) | add([], [1,2], [10,20]) |
=> [11,22] |
||
2 | 2d vector arg(s) | add2([], [1,2], [10,20]) |
=> [11,22] |
||
3 | 3d vector arg(s) | add3([], [1,2,3], [10,20,30]) |
=> [11,22,33] |
||
4 | 4d vector arg(s) | add4([], [1,2,3,4], [10,20,30,40]) |
=> [11,22,33,44] |
||
N2 | 2d vector & scalar | addN2([], [1,2], 10) |
=> [11,12] |
||
N3 | 3d vector & scalar | addN3([], [1,2,3], 10) |
=> [11,12,13] |
||
N4 | 4d vector & scalar | addN4([], [1,2,3,4], 10) |
=> [11,12,13,14] |
||
I | arbitrary len, signed int vec | addI([], [-1,2], [10,-20]) |
=> [9,-18] |
||
U | arbitrary len, unsigned int vec | addU([], [1,2], [10,20]) |
=> [11,22] |
||
I2 / I3 / I4 | fixed size signed int vec | bitnotI3([], [10,-20,30], [7,7,7]) |
=> [-11,19,-31] |
||
U2 / U3 / U4 | fixed size signed int vec | bitnotU3([], [10,20,30], [7,7,7]) |
=> [4294967285,4294967275,4294967265] |
||
NI / NU | arbitrary len, signed int vec & scalar | addNI([], [1,-2,3], 10) |
=> [11,8,13] |
||
NI2 / NI3 / NI4 | fixed size signed int vec & scalar | addNI3([], [1,-2,3], 10) |
=> [11,8,13] |
||
NU2 / NU3 / NU4 | fixed size unsigned int vec & scalar | addNU3([], [1,2,3], 10) |
=> [11,12,13] |
||
S2 / S3 / S4 | fixed size strided vec into unstrided | addS2([], [0,1,0,2], [10,0,20,0], 0,1,0, 1,2,2) |
=> [11,22] |
||
SN2 / SN3 / SN4 | fixed size strided vec & scalar | setSN2([0,0,0,0], 10, 1, 2) |
=> [0,10,0,10] |
||
C | arbitrary len vec, component wise args | setC([], 1,2,3,4) |
=> [1,2,3,4] |
||
C2 / C3 / C4 | fixed size vec, component wise args | setC4([], 1,2,3,4) |
=> [1,2,3,4] |
MAX2
/MAX3
/MAX4
- each component+Infinity
MIN2
/MIN3
/MIN4
- each component-Infinity
ONE2
/ONE3
/ONE4
- each component1
ZERO2
/ZERO3
/ZERO4
- each component0
X2
/X3
/X4
- positive X axisY2
/Y3
/Y4
- positive Y axisZ3
/Z4
- positive Z axisW4
- positive W axis
set
/set2
/set3
/set4
setC
/setC2
/setC3
/setC4
/setC6
setN
/setN2
/setN3
/setN4
setS
/setS2
/setS3
/setS4
setSN2
/setSN3
/setSN4
copy
empty
one
zero
swizzle2
/swizzle3
/swizzle4
setSwizzle1
/setSwizzle2
/setSwizzle3
/setSwizzle4
swapXY
/swapXZ
/swapYZ
Functions to create wrapped (strided) vector instances:
vec2
/vec2n
vec3
/vec3n
vec4
/vec4n
gvec
Wrap existing vanilla vectors:
asVec2
/asVec3
/asVec4
Vanilla vector (array) factories:
ones
zeroes
vecOf
setVN3
/setVN4
setVV4
/setVV6
/setVV9
/setVV16
Component wise op with 2 input vectors:
add
/add2
/add3
/add4
div
/div2
/div3
/div4
mul
/mul2
/mul3
/mul4
sub
/sub2
/sub3
/sub4
fmod
/fmod2
/fmod3
/fmod4
(GLSL behavior)mod
/mod2
/mod3
/mod4
(JS modulo)pow
/pow2
/pow3
/pow4
addI
/addI2
/addI3
/addI4
addU
/addU2
/addU3
/addU4
divI
/divI2
/divI3
/divI4
divU
/divU2
/divU3
/divU4
mulI
/mulI2
/mulI3
/mulI4
mulU
/mulU2
/mulU3
/mulU4
subI
/subI2
/subI3
/subI4
subU
/subU2
/subU3
/subU4
Component wise op with one input vector and single scalar:
addN
/addN2
/addN3
/addN4
divN
/divN2
/divN3
/divN4
mulN
/mulN2
/mulN3
/mulN4
subN
/subN2
/subN3
/subN4
neg
- same asmulN(out, v, -1)
fmodN
/fmodN2
/fmodN3
/fmodN4
(GLSL behavior)modN
/modN2
/modN3
/modN4
(JS modulo)powN
/powN2
/powN3
/powN4
addNI
/addNI2
/addNI3
/addNI4
addNU
/addNU2
/addNU3
/addNU4
divNI
/divNI2
/divNI3
/divNI4
divNU
/divNU2
/divNU3
/divNU4
mulNI
/mulNI2
/mulNI3
/mulNI4
mulNU
/mulNU2
/mulNU3
/mulNU4
subNI
/subNI2
/subNI3
/subNI4
subNU
/subNU2
/subNU3
/subNU4
Functions for memory mapped, strided vectors (without requiring wrappers):
addS2
/addS3
/addS4
divS2
/divS3
/divS4
mulS2
/mulS3
/mulS4
subS2
/subS3
/subS4
addm
/addm2
/addm3
/addm4
addmN
/addmN2
/addmN3
/addmN4
addW2
/addW3
/addW4
/addW5
madd
/madd2
/madd3
/madd4
maddN
/maddN2
/maddN3
/maddN4
subm
/subm2
/subm3
/subm4
submN
/submN2
/submN3
/submN4
clamp
clamp2
/clamp3
/clamp4
clampN
/clampN2
/clampN3
/clampN4
clamp01
/clamp01_2
/clamp01_3
/clamp01_4
clamp11
/clamp11_2
/clamp11_3
/clamp11_4
max
/max2
/max3
/max4
min
/min2
/min3
/min4
cross2
cross3
orthoNormal3
signedArea2
dot
dot2
/dot3
/dot4
dotC4
/dotC6
/dotC8
dotS2
/dotS3
/dotS4
fit
/fit2
/fit3
/fit4
fit01
/fit01_2
/fit01_3
/fit01_4
fit11
/fit11_2
/fit11_3
/fit11_4
mix
/mix2
/mix3
/mix4
mixN
/mixN2
/mixN3
/mixN4
mixBilinear
/mixBilinear2
/mixBilinear3
/mixBilinear4
mixCubic
mixQuadratic
smoothStep
/smoothStep2
/smoothStep3
/smoothStep4
step
/step2
/step3
/step4
limit
mag
magSq
/magSq2
/magSq3
/magSq4
normalize
dist
distSq
/distSq2
/distSq3
/distSq4
distChebyshev
/distChebyshev2
/distChebyshev3
/distChebyshev4
distManhattan
/distManhattan2
/distManhattan3
/distManhattan4
angleBetween2
/angleBetween3
angleRatio
bisect2
degrees
/degrees2
/degrees3
/degrees4
direction
faceForward
heading
/headingXY
/headingXZ
/headingYZ
headingSegment
/headingSegmentXY
/headingSegmentXZ
/headingSegmentYZ
normalLeft2
/normalRight2
perpendicularLeft2
/perpendicularRight2
project
radians
/radians2
/radians3
/radians4
reflect
refract
(Also see rotation matrices provided by @thi.ng/matrices)
rotateAroundAxis3
rotateAroundPoint2
rotateX
\rotateY
\rotateZ
cartesian
/cartesian2
/cartesian3
polar
/polar2
/polar3
All ops support custom PRNG impls based on the
@thi.ng/random
IRandom
interface and use Math.random
by default:
jitter
randMinMax
/randMinMax2
/randMinMax3
/randMinMax4
randNorm
random
/random2
/random3
/random4
abs
/abs2
/abs3
/abs4
acos
/acos2
/acos3
/acos4
asin
/asin2
/asin3
/asin4
atan
/atan2
/atan3
/atan4
ceil
/ceil2
/ceil3
/ceil4
cos
/cos2
/cos3
/cos4
cosh
/cosh2
/cosh3
/cosh4
exp
/exp2
/exp3
/exp4
floor
/floor2
/floor3
/floor4
fmod
/fmod2
/fmod3
/fmod4
(C / GLSL modulo)fract
/fract2
/fract3
/fract4
fromHomogeneous
/fromHomogeneous3
/fromHomogeneous4
invert
/invert2
/invert3
/invert4
invSqrt
/invSqrt2
/invSqrt3
/invSqrt4
log
/log2
/log3
/log4
major
/major2
/major3
/major4
minor
/minor2
/minor3
/minor4
mod
/mod2
/mod3
/mod4
(JS modulo)round
/round2
/round3
/round4
sign
/sign2
/sign3
/sign4
sin
/sin2
/sin3
/sin4
sinh
/sinh2
/sinh3
/sinh4
sqrt
/sqrt2
/sqrt3
/sqrt4
sum
/sum2
/sum3
/sum4
tan
/tan2
/tan3
/tan4
tanh
/tanh2
/tanh3
/tanh4
trunc
/trunc2
/trunc3
/trunc4
wrap
/wrap2
/wrap3
/wrap4
Functions to transform flat / strided buffers w/ vector operations:
mapV
/mapVN
/mapVV
/mapVVN
/mapVVV
comparator2
/comparator3
/comparator4
eqDelta
/eqDelta2
/eqDelta3
/eqDelta4
eqDeltaS
eqDeltaArray
Arguments are assumed to be signed / unsigned ints. Results will be forced accordingly.
bitAndI
/bitAndI2
/bitAndI3
/bitAndI4
bitAndU
/bitAndU2
/bitAndU3
/bitAndU4
bitAndNI
/bitAndNI2
/bitAndNI3
/bitAndNI4
bitAndNU
/bitAndNU2
/bitAndNU3
/bitAndNU4
bitNotI
/bitNotI2
/bitNotI3
/bitNotI4
(unary)bitNotU
/bitNotU2
/bitNotU3
/bitNotU4
(unary)bitOrI
/bitOrI2
/bitOrI3
/bitOrI4
bitOrU
/bitOrU2
/bitOrU3
/bitOrU4
bitOrNI
/bitOrNI2
/bitOrNI3
/bitOrNI4
bitOrNU
/bitOrNU2
/bitOrNU3
/bitOrNU4
bitXorI
/bitXorI2
/bitXorI3
/bitXorI4
bitXorU
/bitXorU2
/bitXorU3
/bitXorU4
bitXorNI
/bitXorNI2
/bitXorNI3
/bitXorNI4
bitXorNU
/bitXorNU2
/bitXorNU3
/bitXorNU4
lshiftI
/lshiftI4
/lshiftI4
/lshiftI4
lshiftU
/lshiftU4
/lshiftU4
/lshiftU4
rshiftI
/rshiftI2
/rshiftI3
/rshiftI4
rshiftU
/rshiftU2
/rshiftU3
/rshiftU4
logicAnd
/logicAnd2
/logicAnd3
/logicAnd4
logicOr
/logicOr2
/logicOr3
/logicOr4
logicNot
/logicNot2
/logicNot3
/logicNot4
All resulting in boolean vectors:
lt
/lt2
/lt3
/lt4
lte
/lte2
/lte3
/lte4
gt
/gt2
/gt3
/gt4
gte
/gte2
/gte3
/gte4
eq
/eq2
/eq3
/eq4
neq
/neq2
/neq3
/neq4
hash
compile
/compileG
/compileGHOF
/compileHOF
defOp
/defOpS
/defFnOp
/defHofOp
defMathNOp
/defMathOp
vop
For more information about the code generator see:
- Karsten Schmidt
© 2018 Karsten Schmidt // Apache Software License 2.0