@thi.ng/vectors
This project is part of the
@thi.ng/umbrella monorepo.
About
This package provides vector and matrix operations as plain functions
and class wrappers with fluid interface. All functions support any array
/ typed array storage, incl. mapped views of larger buffers (e.g. for
WebGL / WASM interop, pixel buffers). Additionally, vectors support
flexible data layouts, incl. AOS /
SOA, striped, interleaved,
aligned etc.
Vectors
In addition to arbitrary sized
vectors,
the library provides these optimized fixed-sized versions:
Vector classes
All of the vector operations listed below are also available via class
wrappers of strided buffer views. These vector classes (Vec2/3/4
) are
array-like themselves and provide array index and .x
, .y
, .z
, .w
property accessors (including .length
). The GVec
class wrapper only
provides .length
read access. All classes are also iterable.
buf = [0, 1, 0, 2, 0, 3];
a = new v.Vec3(buf, 1, 2);
a[0] *= 10;
a[1] *= 100;
a[2] *= 1000;
a.x
a.y
a.z
a.length
[...a]
buf
Supported operations
Note: Most functions are provided in different (optimized) versions,
depending on vector size. E.g. add
performs vector addition for
arbitrary sizes, add2
for 2D vectors, add3
for 3D, add4
for 4D...
Class wrapper methods use the non-suffixed naming.
All vector operations (regardless of size) operate on any array-like
buffer and accept optional start indices and component strides (number
of elements (+1) between individual vector components). This allows for
zero-copy vector operations on sections of larger buffers. The default
start index is 0, default stride 1. See examples below and
tests.
Operation | Generic | 2D | 3D | 4D |
---|
Get vector (dense copy) | get | get2 | get3 | get4 |
Set vector components (vector) | set | set2 | set3 | set4 |
Set vector components (uniform) | setN | setN2 | setN3 | setN4 |
Set vector components (scalars) | | setS2 | setS3 | setS4 |
Swizzle vector components | | swizzle2 | swizzle3 | swizzle4 |
Equality (w/ epsilon) | eqDelta | eqDelta2 | eqDelta3 | eqDelta4 |
Vector addition | add | add2 | add3 | add4 |
Vector subtraction | sub | sub2 | sub3 | sub4 |
Vector multiplication | mul | mul2 | mul3 | mul4 |
Vector division | div | div2 | div3 | div4 |
Uniform scalar addition | addN | addN2 | addN3 | addN4 |
Uniform scalar subtraction | subN | subN2 | subN3 | subN4 |
Uniform scalar multiply | mulN | mulN2 | mulN3 | mulN4 |
Uniform scalar multiply | divN | divN2 | divN3 | divN4 |
Vector negation | neg | neg2 | neg3 | neg4 |
Multiply-add vectors | madd | madd2 | madd3 | madd4 |
Multiply-add scalar | maddN | maddN2 | maddN3 | maddN4 |
Linear interpolation (vector) | mix | mix2 | mix3 | mix4 |
Linear interpolation (uniform) | mixN | mixN2 | mixN3 | mixN4 |
Dot product | dot | dot2 | dot3 | dot4 |
Cross product | | cross2 | cross3 | |
Magnitude | mag | mag2 | mag3 | mag4 |
Magnitude (squared) | magSq | magSq2 | magSq3 | magSq4 |
Normalize (w/ opt length) | normalize | normalize2 | normalize3 | normalize4 |
Limit to length | | limit2 | limit3 | limit4 |
Distance | dist | dist2 | dist3 | dist4 |
Distance (squared) | distSq | distSq2 | distSq3 | distSq4 |
Manhattan distance | | distManhattan2 | distManhattan3 | distManhattan4 |
Chebyshev distance | | distChebyshev2 | distChebyshev3 | distChebyshev4 |
Reflection | | reflect2 | reflect3 | reflect4 |
RotationX | | | rotateX3 | |
RotationY | | | rotateY3 | |
RotationZ | | rotate2 | rotateZ3 | |
Heading XY | | heading2 | headingXY3 | |
Heading XZ | | | headingXZ3 | |
Heading YZ | | | headingYZ3 | |
Cartesian -> Polar | | toPolar2 | toSpherical3 | |
Polar -> Cartesian | | toCartesian2 | toCartesian3 | |
Cartesian -> Cylindrical | | | toCylindrical3 | |
Cylindrical -> Cartesian | | | fromCylindrical3 | |
Minor axis | | minorAxis2 | minorAxis3 | minorAxis4 |
Major axis | | majorAxis2 | majorAxis3 | majorAxis4 |
Minimum | min | min2 | min3 | min4 |
Maximum | max | max2 | max3 | max4 |
Range clamping | clamp | clamp2 | clamp3 | clamp4 |
Step (like GLSL) | step | step2 | step3 | step4 |
SmoothStep (like GLSL) | smoothStep | smoothStep2 | smoothStep3 | smoothStep4 |
Absolute value | abs | abs2 | abs3 | abs4 |
Sign (w/ opt epsilon) | sign | sign2 | sign3 | sign4 |
Round down | floor | floor2 | floor3 | floor4 |
Round up | ceil | ceil2 | ceil3 | ceil4 |
Square root | sqrt | sqrt2 | sqrt3 | sqrt4 |
Power (vector) | pow | pow2 | pow3 | pow4 |
Power (uniform) | powN | powN2 | powN3 | powN4 |
Matrices
All matrix types are in WebGL layout (column major) and densely packed
(stride always 1). As with vectors, class wrapper methods use the
non-suffixed naming.
Operation | 2x3 | 3x3 | 4x4 |
---|
Set identity | identity23 | identity33 | identity44 |
Get matrix components (dense copy) | get23 | get33 | get44 |
Set matrix components (matrix) | set23 | set33 | set44 |
Set matrix components (scalars) | setS23 | setS33 | setS44 |
Create rotation matrix | | rotationX33 | rotationX44 |
| | rotationY33 | rotationY44 |
| rotation23 | rotationZ33 | rotationZ44 |
| rotationAroundPoint23 | | |
Create scale matrix (vector) | scaleV23 | scaleV33 | scaleV44 |
Create scale matrix (uniform) | scaleN23 | scaleN33 | scaleN44 |
Create scale matrix (scalars) | scaleS23 | scaleS33 | scaleS44 |
| scaleWithCenter23 | | scaleWithCenter44 |
Create translation matrix (vector) | translationV23 | | translationV44 |
Create translation matrix (scalars) | translationS23 | | translationS44 |
Create skew matrix | skewX23 / shearX23 | | |
| skewY23 / shearY23 | | |
Create projection matrix | | | projection |
| | | ortho |
| | | frustum |
Create camera matrix | | | lookAt |
Matrix multiply | mul23 | mul33 | mul44 |
Matrix concatenation (multiple) | concat23 | concat33 | concat44 |
Matrix vector multiply | mulV23 | mulV33 | mulV44 (Vec4) |
| | | mulV344 (Vec3) |
Determinant | det23 | det33 | det44 |
Matrix inversion | invert23 | invert33 | invert44 |
Matrix transpose | | transpose33 | transpose44 |
Installation
yarn add @thi.ng/vectors
Usage examples
Basics
import * as v from "@thi.ng/vectors";
v.add4([1, 2, 3, 4], [10, 20, 30, 40]);
points = [1, 4, 7, 2, 5, 8, 3, 6, 9];
v.add3(points, [100, 200, 300], 0, 0, 3, 1);
v.add3(points, [100, 200, 300], 1, 0, 3, 1);
v.add3(points, [100, 200, 300], 2, 0, 3, 1);
v.get3(v.add3(points, points, 0, 2, 3, 3), 0, 3);
v.swizzle4([], [10, 20, 30, 40], 1, 0, 3, 2);
v.swizzle4([], [10, 20, 30, 40], 0, 0, 2, 2);
norm = v.normalize([1, 2, 3, 4, 5, 6, 7, 8, 6, 4]);
v.mag(norm);
Vector classes & interleaved vectors in large buffer
buf = [
0,0,0, 0,0, 1,0,0,1,
100,0,0, 1,0, 1,1,0,1,
100,100,0, 1,1, 1,0,1,1,
0,100,0, 0,1, 0,1,1,1,
];
pos = v.Vec3.mapBuffer(buf, 4, 0, 1, 9);
uv = v.Vec2.mapBuffer(buf, 4, 3, 1, 9);
col = v.Vec4.mapBuffer(buf, 4, 5, 1, 9);
console.log(`pos: ${pos[1]}, uv: ${uv[1]}, color: ${col[1]}`);
centroid = pos.reduce((c, p) => c.add(p), v.vec3()).divN(pos.length);
tx = v.Mat44.concat(
v.Mat44.scale(0.01),
v.Mat44.translation(centroid.copy().neg()),
v.Mat44.rotationZ(v.rad(90)),
);
pos.forEach((p) => tx.mulV3(p));
Image RGB grayscale conversion
canvas = document.getElementById("main");
img = canvas.getContext("2d").getImageData(0,0, canvas.width, canvas.height);
v.transformVectors1(
(a, b, ia, ib, sa, sb) =>
v.setN3(a, v.dot3(a, b, ia, ib, sa, sb), ia, sa),
img,
[0.29, 0.6, 0.11],
canvas.width * canvas.height,
0, 0,
1, 1,
4
);
Authors
License
© 2016 - 2018 Karsten Schmidt // Apache Software License 2.0