@thi.ng/vectors
Version:
Optimized 2d/3d/4d and arbitrary length vector operations, support for memory mapping/layouts
778 lines (634 loc) • 48.4 kB
Markdown
<!-- This file is generated - DO NOT EDIT! -->
<!-- Please see: https://github.com/thi-ng/umbrella/blob/develop/CONTRIBUTING.md#changes-to-readme-files -->
# 
[](https://www.npmjs.com/package/@thi.ng/vectors)

[](https://mastodon.thi.ng/@toxi)
> [!NOTE]
> This is one of 205 standalone projects, maintained as part
> of the [.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo
> and anti-framework.
>
> 🚀 Please help me to work full-time on these projects by [sponsoring me on
> GitHub](https://github.com/sponsors/postspectacular). Thank you! ❤️
- [About](#about)
- [Features](#features)
- [Status](#status)
- [Breaking changes in v6.0.0](#breaking-changes-in-v600)
- [Breaking changes in v3.0.0](#breaking-changes-in-v300)
- [Related packages](#related-packages)
- [Installation](#installation)
- [Dependencies](#dependencies)
- [Usage examples](#usage-examples)
- [API](#api)
- [Basic usage](#basic-usage)
- [Naming conventions](#naming-conventions)
- [Constants](#constants)
- [Component setters & copying](#component-setters--copying)
- [Component swizzling](#component-swizzling)
- [Vector creation](#vector-creation)
- [Basic vector math](#basic-vector-math)
- [Vector / vector](#vector--vector)
- [Vector / scalar](#vector--scalar)
- [Combined operations](#combined-operations)
- [Constraints](#constraints)
- [Cross product](#cross-product)
- [Dot product](#dot-product)
- [Interpolation](#interpolation)
- [Normalization / magnitude](#normalization--magnitude)
- [Distances](#distances)
- [Orientation](#orientation)
- [Rotations](#rotations)
- [Polar / cartesian conversion](#polar--cartesian-conversion)
- [Randomness](#randomness)
- [Unary vector math ops](#unary-vector-math-ops)
- [Vector array batch processing](#vector-array-batch-processing)
- [Comparison / equality](#comparison--equality)
- [Bitwise operations (int / uint vec)](#bitwise-operations-int--uint-vec)
- [Vector conversions / coercions](#vector-conversions--coercions)
- [Boolean vector logic](#boolean-vector-logic)
- [Componentwise comparisons](#componentwise-comparisons)
- [Hashing](#hashing)
- [Code generator](#code-generator)
- [Authors](#authors)
- [License](#license)
## About
Optimized 2d/3d/4d and arbitrary length vector operations, support for memory mapping/layouts.
Likely the most comprehensive vector library for TypeScript / JavaScript
currently available.
This package provides **over 875(!) 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](https://en.wikipedia.org/wiki/AoS_and_SoA)).
Includes componentwise logic operations for boolean vectors, componentwise
comparisons for numeric vectors and componentwise binary ops for signed &
unsigned integer vectors.
### Features
- Small & fast: The vast majority of functions are code generated with
fixed-sized versions not using any loops. Minified + gzipped, the entire
package is ~11.8KB (though you'll hardly ever use all functions).
- 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`](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/add.ts)
performs vector addition on arbitrary-length vectors, `add2`, `add3`, `add4`
are the optimized version for fixed-length vectors...
- Pluggable interface: The [`VecAPI`
interface](https://docs.thi.ng/umbrella/vectors/interfaces/VecAPI.html)
defines objects of the ~70 most common vector operations implemented for
specific vector sizes. Using this interface simplifies performance-critical
use cases & algorithms which target different dimensions (e.g. 2d/3d),
but should use the avaiable size-optimized vector ops. See
[`VEC2`](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/vec2-api.ts),
[`VEC3`](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/vec3-api.ts)
and
[`VEC4`](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/vec4-api.ts)
- Extensible: Custom vector ops can be defined in a similar manner using the
provided code generation helpers (see
[vop.ts](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/vop.ts)
and
[emit.ts](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/compile/emit.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
(usually) be used as output (i.e. for mutation).
- Strided vector support is handled via the lightweight
[`Vec2/3/4`](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/vec2.ts)
class wrappers and the
[`gvec()`](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/gvec.ts)
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 with `S`, e.g.
[`addS`](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/adds.ts)
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
[.ng/random](https://github.com/thi-ng/umbrella/tree/develop/packages/random)
to work with custom (P)RNGs. If omitted, the built-in `Math.random()` will be
used.
Partially ported from [thi.ng/geom-clj](http://thi.ng/geom-clj) (Clojure) and
[c.thi.ng](http://c.thi.ng) (C11).
## Status
**STABLE** - used in production
[Search or submit any issues for this package](https://github.com/thi-ng/umbrella/issues?q=%5Bvectors%5D+in%3Atitle)
### Breaking changes in v6.0.0
The introduction of seveveral standard [libc math
functions](https://www.cplusplus.com/reference/cmath/) to the
[.ng/math](https://github.com/thi-ng/umbrella/tree/develop/packages/math)
package caused a behavior change of existing `fmod()` function. For symmetry
reasons the same changes have been applied to this package...
- swap `fmod()` ⇄ `mod()`, to align the latter with its GLSL counterpart
- the new `fmod()` has standard libc behavior (same as JS `%` operator)
- add `remainder()` with standard libc behavior
### Breaking changes in v3.0.0
- to avoid confusion, the arg order of `madd` and `maddN` functions have
been updated to be compatible with the OpenCL `mad` function and to
generally follow the expanded name, i.e. multiply-add:
- `madd([], a, b, c)`: before `a + 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`
## Related packages
- [.ng/color](https://github.com/thi-ng/umbrella/tree/develop/packages/color) - Array-based color types, CSS parsing, conversions, transformations, declarative theme generation, gradients, presets
- [.ng/distance](https://github.com/thi-ng/umbrella/tree/develop/packages/distance) - N-dimensional distance metrics & K-nearest neighborhoods for point queries
- [.ng/ecs](https://github.com/thi-ng/umbrella/tree/develop/packages/ecs) - Entity Component System based around typed arrays & sparse sets
- [.ng/geom](https://github.com/thi-ng/umbrella/tree/develop/packages/geom) - Functional, polymorphic API for 2D geometry types & SVG generation
- [.ng/hdom-canvas](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom-canvas) - [@thi.ng/hdom](https://github.com/thi-ng/umbrella/tree/develop/packages/hdom) component wrapper for declarative canvas scenegraphs
- [.ng/imgui](https://github.com/thi-ng/umbrella/tree/develop/packages/imgui) - Immediate mode GUI with flexible state handling & data only shape output
- [.ng/matrices](https://github.com/thi-ng/umbrella/tree/develop/packages/matrices) - Matrix & quaternion operations for 2D/3D geometry processing
- [.ng/simd](https://github.com/thi-ng/umbrella/tree/develop/packages/simd) - WASM based SIMD vector operations for batch processing
- [.ng/soa](https://github.com/thi-ng/umbrella/tree/develop/packages/soa) - SOA & AOS memory mapped structured views with optional & extensible serialization
- [.ng/shader-ast-js](https://github.com/thi-ng/umbrella/tree/develop/packages/shader-ast-js) - Customizable JS codegen, compiler & runtime for [@thi.ng/shader-ast](https://github.com/thi-ng/umbrella/tree/develop/packages/shader-ast)
- [.ng/vector-pools](https://github.com/thi-ng/umbrella/tree/develop/packages/vector-pools) - Data structures for managing & working with strided, memory mapped vectors
- [.ng/webgl](https://github.com/thi-ng/umbrella/tree/develop/packages/webgl) - WebGL & GLSL abstraction layer
## Installation
```bash
yarn add .ng/vectors
```
ESM import:
```ts
import * as vec from "@thi.ng/vectors";
```
Browser ESM import:
```html
<script type="module" src="https://esm.run/@thi.ng/vectors"></script>
```
[JSDelivr documentation](https://www.jsdelivr.com/)
For Node.js REPL:
```js
const vec = await import("@thi.ng/vectors");
```
Package sizes (brotli'd, pre-treeshake): ESM: 14.03 KB
## Dependencies
- [.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
- [.ng/binary](https://github.com/thi-ng/umbrella/tree/develop/packages/binary)
- [.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
- [.ng/equiv](https://github.com/thi-ng/umbrella/tree/develop/packages/equiv)
- [.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
- [.ng/math](https://github.com/thi-ng/umbrella/tree/develop/packages/math)
- [.ng/memoize](https://github.com/thi-ng/umbrella/tree/develop/packages/memoize)
- [.ng/random](https://github.com/thi-ng/umbrella/tree/develop/packages/random)
- [.ng/strings](https://github.com/thi-ng/umbrella/tree/develop/packages/strings)
- [.ng/transducers](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers)
Note: .ng/api is in _most_ cases a type-only import (not used at runtime)
## Usage examples
36 projects in this repo's
[/examples](https://github.com/thi-ng/umbrella/tree/develop/examples)
directory are using this package:
| Screenshot | Description | Live demo | Source |
|:-------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------|:------------------------------------------------------------|:-----------------------------------------------------------------------------------------|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/ascii-raymarch.jpg" width="240"/> | ASCII art raymarching with thi.ng/shader-ast & thi.ng/text-canvas | [Demo](https://demo.thi.ng/umbrella/ascii-raymarch/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/ascii-raymarch) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/boid-basics.png" width="240"/> | Basic 2D boid simulation and spatial indexing neighbor lookups | [Demo](https://demo.thi.ng/umbrella/boid-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/boid-basics) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/canvas-dial.png" width="240"/> | Canvas based dial widget | [Demo](https://demo.thi.ng/umbrella/canvas-dial/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/canvas-dial) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/canvas-recorder.png" width="240"/> | Self-modifying, animated typographic grid with emergent complex patterns | [Demo](https://demo.thi.ng/umbrella/canvas-recorder/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/canvas-recorder) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/ellipse-proximity.png" width="240"/> | Interactive visualization of closest points on ellipses | [Demo](https://demo.thi.ng/umbrella/ellipse-proximity/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/ellipse-proximity) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-csv-piechart.png" width="240"/> | Piechart visualization of CSV data | [Demo](https://demo.thi.ng/umbrella/geom-csv-piechart/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-csv-piechart) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-knn.jpg" width="240"/> | Doodle w/ K-nearest neighbor search result visualization | [Demo](https://demo.thi.ng/umbrella/geom-knn/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-knn) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-knn-hash.jpg" width="240"/> | K-nearest neighbor search in an hash grid | [Demo](https://demo.thi.ng/umbrella/geom-knn-hash/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-knn-hash) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-sdf-path.png" width="240"/> | SVG path to SDF, applying deformation and converting back to SVG | [Demo](https://demo.thi.ng/umbrella/geom-sdf-path/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-sdf-path) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/gesture-analysis.png" width="240"/> | Mouse gesture / stroke analysis, simplification, corner detection | [Demo](https://demo.thi.ng/umbrella/gesture-analysis/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/gesture-analysis) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/hdom-canvas-clock.png" width="240"/> | Realtime analog clock demo | [Demo](https://demo.thi.ng/umbrella/hdom-canvas-clock/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-canvas-clock) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/hdom-canvas-draw.jpg" width="240"/> | Interactive pattern drawing demo using transducers | [Demo](https://demo.thi.ng/umbrella/hdom-canvas-draw/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-canvas-draw) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/hdom-canvas-particles.jpg" width="240"/> | 2D Bezier curve-guided particle system | [Demo](https://demo.thi.ng/umbrella/hdom-canvas-particles/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-canvas-particles) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/hdom-canvas/hdom-canvas-shapes-results.png" width="240"/> | Various hdom-canvas shape drawing examples & SVG conversion / export | [Demo](https://demo.thi.ng/umbrella/hdom-canvas-shapes/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-canvas-shapes) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/imgui/imgui-all.png" width="240"/> | Canvas based Immediate Mode GUI components | [Demo](https://demo.thi.ng/umbrella/imgui/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/imgui) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/geom/geom-isoline.png" width="240"/> | Animated sine plasma effect visualized using contour lines | [Demo](https://demo.thi.ng/umbrella/iso-plasma/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/iso-plasma) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/kmeans-viz.jpg" width="240"/> | k-means clustering visualization | [Demo](https://demo.thi.ng/umbrella/kmeans-viz/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/kmeans-viz) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/optical-flow.avif" width="240"/> | Optical flow analysis of web cam or video inputs | [Demo](https://demo.thi.ng/umbrella/optical-flow/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/optical-flow) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/poly-subdiv.jpg" width="240"/> | Animated, iterative polygon subdivisions & visualization | [Demo](https://demo.thi.ng/umbrella/poly-subdiv/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/poly-subdiv) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/quasi-lattice.png" width="240"/> | Quasi-random lattice generator | [Demo](https://demo.thi.ng/umbrella/quasi-lattice/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/quasi-lattice) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/ramp-synth.png" width="240"/> | Unison wavetable synth with waveform editor | [Demo](https://demo.thi.ng/umbrella/ramp-synth/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/ramp-synth) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rasterize-blend.jpg" width="240"/> | Steering behavior drawing with alpha-blended shapes | [Demo](https://demo.thi.ng/umbrella/rasterize-blend/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rasterize-blend) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-canvas-basics.jpg" width="240"/> | Minimal rdom-canvas animation | [Demo](https://demo.thi.ng/umbrella/rdom-canvas-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-canvas-basics) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rotating-voronoi.jpg" width="240"/> | Animated Voronoi diagram, cubic splines & SVG download | [Demo](https://demo.thi.ng/umbrella/rotating-voronoi/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rotating-voronoi) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/scenegraph.png" width="240"/> | 2D scenegraph & shape picking | [Demo](https://demo.thi.ng/umbrella/scenegraph/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/scenegraph) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/scenegraph-image.png" width="240"/> | 2D scenegraph & image map based geometry manipulation | [Demo](https://demo.thi.ng/umbrella/scenegraph-image/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/scenegraph-image) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/shader-graph.jpg" width="240"/> | Minimal shader graph developed during livestream #2 | [Demo](https://demo.thi.ng/umbrella/shader-graph/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/shader-graph) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/simd-plot.png" width="240"/> | Fitting, transforming & plotting 10k data points per frame using SIMD | [Demo](https://demo.thi.ng/umbrella/simd-plot/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/simd-plot) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/soa-ecs-100k.png" width="240"/> | Entity Component System w/ 100k 3D particles | [Demo](https://demo.thi.ng/umbrella/soa-ecs/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/soa-ecs) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/spline-tangent.png" width="240"/> | Compute cubic spline position & tangent using Dual Numbers | [Demo](https://demo.thi.ng/umbrella/spline-tangent/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/spline-tangent) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/text-canvas.png" width="240"/> | 3D wireframe textmode demo | [Demo](https://demo.thi.ng/umbrella/text-canvas/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/text-canvas) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/unbiased-normals.png" width="240"/> | Visual comparison of biased vs. unbiased normal vectors projected on the surface of a sphere | [Demo](https://demo.thi.ng/umbrella/unbiased-normals/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/unbiased-normals) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/webgl-cube.png" width="240"/> | WebGL multi-colored cube mesh | [Demo](https://demo.thi.ng/umbrella/webgl-cube/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/webgl-cube) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/webgl-float-fbo.jpg" width="240"/> | Drawing to floating point offscreen / multi-pass shader pipeline | [Demo](https://demo.thi.ng/umbrella/webgl-float-fbo/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/webgl-float-fbo) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/webgl-grid.jpg" width="240"/> | WebGL instancing, animated grid | [Demo](https://demo.thi.ng/umbrella/webgl-grid/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/webgl-grid) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/webgl-msdf.jpg" width="240"/> | WebGL MSDF text rendering & particle system | [Demo](https://demo.thi.ng/umbrella/webgl-msdf/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/webgl-msdf) |
## API
[Generated API docs](https://docs.thi.ng/umbrella/vectors/)
### Basic usage
```ts
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 (output) is null writes result to 2nd arg)
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]
// or operate on raw arrays directly...
// here the last 4 args define:
// out index, src index, out stride, src stride
v.addNS3(null, [0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0], 10, 1, 1, 4, 4)
// [0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0]
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
```
Using the
[`VecAPI`](https://docs.thi.ng/umbrella/vectors/interfaces/VecAPI.html)
implementation objects to use size-optimized vector ops in a pluggable manner
(this is in addition/alternative to using the standard set of polymorphic
functions for similar results).
```ts
import { VEC2, VEC3, type Vec, type VecAPI } from "@thi.ng/vectors";
interface Particle {
pos: Vec;
dir: Vec;
targetDir: Vec;
speed: number;
turnSpeed: number;
}
const updateParticle = (p: Particle, { maddN, mixN, normalize }: VecAPI) => {
// interpolate current direction toward target dir
mixN(null, p.dir, p.targetDir, p.turnSpeed);
// normalize direction
normalize(null, p.dir);
// add scaled direction to position (and store as new position)
return maddN(p.pos, p.dir, p.speed, p.pos);
};
// 2d version
let p2d: Particle = {
pos: [10, 20], dir: [0, 1], targetDir: [1, 0], speed: 5, turnSpeed: 0.1,
};
updateParticle(p2d, VEC2);
// [ 10.552, 24.969 ]
// 3d version
let p3d: Particle = {
pos: [10, 20, 30], dir: [0, 1, 0], targetDir: [0, 0, 1], speed: 5, turnSpeed: 0.1,
};
updateParticle(p3d, VEC3);
// [ 10, 24.969, 30.552 ]
```
### Naming conventions
Wherever possible, each operation comes in different variations. All fixed size
versions use optimized, loop-free implementations.
| Suffix | Description |
|-----------------|----------------------------------------|
| none | arbitrary length vector arg(s) |
| 2 | 2d vector arg(s) |
| 3 | 3d vector arg(s) |
| 4 | 4d vector arg(s) |
| N2 | 2d vector(s) & scalar |
| N3 | 3d vector(s) & scalar |
| N4 | 4d vector(s) & scalar |
| I | arbitrary len, signed int vec |
| U | arbitrary len, unsigned int vec |
| I2 / I3 / I4 | fixed size signed int vec |
| U2 / U3 / U4 | fixed size signed int vec |
| NI / NU | arbitrary len, signed int vec & scalar |
| NI2 / NI3 / NI4 | fixed size signed int vec & scalar |
| NU2 / NU3 / NU4 | fixed size unsigned int vec & scalar |
| S2 / S3 / S4 | fixed size strided vec |
| NS2 / NS3 / NS4 | fixed size strided vec & scalar |
| C | arbitrary len vec, component wise args |
| C2 / C3 / C4 | fixed size vec, component wise args |
| CS2 / CS3 / CS4 | fixed size strided vec, component args |
### Constants
- `MAX2` / `MAX3` / `MAX4` - each component `+Infinity`
- `MIN2` / `MIN3` / `MIN4` - each component `-Infinity`
- `ONE2` / `ONE3` / `ONE4` - each component `1`
- `ZERO2` / `ZERO3` / `ZERO4` - each component `0`
- `X2` / `X3` / `X4` - positive X axis
- `Y2` / `Y3` / `Y4` - positive Y axis
- `Z3` / `Z4` - positive Z axis
- `W4` - positive W axis
### Component setters & copying
- `set` / `set2` / `set3` / `set4`
- `setC` / `setC2` / `setC3` / `setC4` / `setC6`
- `setN` / `setN2` / `setN3` / `setN4`
- `setS` / `setS2` / `setS3` / `setS4`
- `setCS2` / `setCS3` / `setCS4`
- `setNS2` / `setNS3` / `setNS4`
- `copy`
- `empty`
- `one`
- `zero`
### Component swizzling
- `swizzle2` / `swizzle3` / `swizzle4`
- `setSwizzle1` / `setSwizzle2` / `setSwizzle3` / `setSwizzle4`
- `swapXY` / `swapXZ` / `swapYZ`
### Vector creation
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`
### Basic vector math
#### Vector / vector
Component wise op with 2 input vectors:
| Function | Generic | Fixed | Strided | Int | Comments |
|-------------|---------|-------|---------|--------------|-----------------|
| `add` | ✓ | 2-4 | S2-S4 | I2-I4, U2-U4 | |
| `div` | ✓ | 2-4 | S2-S4 | I2-I4, U2-U4 | |
| `mul` | ✓ | 2-4 | S2-S4 | I2-I4, U2-U4 | |
| `sub` | ✓ | 2-4 | S2-S4 | I2-I4, U2-U4 | |
| `fmod` | ✓ | 2-4 | | | (C/JS behavior) |
| `mod` | ✓ | 2-4 | | | (GLSL behavior) |
| `pow` | ✓ | 2-4 | | | |
| `remainder` | ✓ | 2-4 | | | (C behavior) |
```ts
import { add, add2, addU2, addS2 } from "@thi.ng/vectors";
// generic
add([], [1, 2, 3, 4, 5], [10, 20, 30, 40, 50]);
// [11, 22, 33, 44, 55]
// fixed size & packed
add2([], [1, 2], [10, 20])
// [11, 22]
// unsigned int
addU2([], [1, -2], [-10, 20])
// [4294967287, 18]
// strided
addS2([], [1,0,2,0], [0,10,0,0,0,20], 0, 0, 1, 1, 2, 4)
// [11, 22]
```
#### Vector / scalar
Component wise op with one input vector and single scalar:
| Function | Generic | Fixed | Strided | Int | Comments |
|--------------|---------|-------|---------|--------------|----------------------------|
| `addN` | ✓ | 2-4 | S2-S4 | I2-I4, U2-U4 | |
| `divN` | ✓ | 2-4 | S2-S4 | I2-I4, U2-U4 | |
| `mulN` | ✓ | 2-4 | S2-S4 | I2-I4, U2-U4 | |
| `subN` | ✓ | 2-4 | S2-S4 | I2-I4, U2-U4 | |
| `neg` | ✓ | | | | same as `mulN(out, v, -1)` |
| `fmodN` | ✓ | 2-4 | | | (C/JS behavior) |
| `modN` | ✓ | 2-4 | | | (GLSL behavior) |
| `powN` | ✓ | 2-4 | | | |
| `remainderN` | ✓ | 2-4 | | | (C behavior) |
| `roundN` | ✓ | 2-4 | | | |
### Combined operations
| Function | Generic | Fixed | Strided | Int | Comments |
|----------|---------|-------|---------|-----|-------------|
| `addm` | ✓ | 2-4 | S2-S4 | | (a + b) * c |
| `addmN` | ✓ | 2-4 | S2-S4 | | (a + b) * n |
| `madd` | ✓ | 2-4 | S2-S4 | | a * n + c |
| `maddN` | ✓ | 2-4 | S2-S4 | | a * n + b |
| `msub` | ✓ | 2-4 | S2-S4 | | a * n - c |
| `msubN` | ✓ | 2-4 | S2-S4 | | a * n - b |
| `subm` | ✓ | 2-4 | S2-S4 | | (a - b) * c |
| `submN` | ✓ | 2-4 | S2-S4 | | (a - b) * n |
### Constraints
| Function | Generic | Fixed | Strided | Int | Comments |
|-----------|---------|---------|---------|-----|----------------------|
| `clamp` | ✓ | 2-4 | | | `min(max(a, b), c)` |
| `clampN` | ✓ | 2-4 | | | `min(max(a, n), m)` |
| `clamp01` | ✓ | _2 - _4 | | | `min(max(a, 0), 1)` |
| `clamp11` | ✓ | _2 - _4 | | | `min(max(a, -1), 1)` |
| `max` | ✓ | 2-4 | | | `max(a, b)` |
| `min` | ✓ | 2-4 | | | `min(a, b)` |
### Cross product
| Function | Generic | Fixed | Strided | Int | Comments |
|---------------|---------|-------|---------|-----|---------------------------|
| `cross` | | 2, 3 | S2, S3 | | 2D version returns scalar |
| `orthoNormal` | | 3 | | | |
| `signedArea` | | 2 | | | |
### Dot product
| Function | Generic | Fixed | Strided | Cwise | Comments |
|----------|---------|-------|---------|------------|----------|
| `dot` | ✓ | 2-4 | S2-S4 | C4, C6, C8 | |
### Interpolation
| Function | Generic | Fixed | Strided | Int | Comments |
|----------------|---------|---------|---------|-----|----------|
| `fit` | ✓ | 2-4 | | | |
| `fit01` | ✓ | _2 - _4 | | | |
| `fit11` | ✓ | _2 - _4 | | | |
| `mix` | ✓ | 2-4 | S2 - S4 | | |
| `mixN` | ✓ | 2-4 | S2 - S4 | | |
| `mixBilinear` | ✓ | 2-4 | | | |
| `mixCubic` | ✓ | | | | |
| `mixQuadratic` | ✓ | | | | |
| `smoothStep` | ✓ | 2-4 | | | |
| `step` | ✓ | 2-4 | | | |
### Normalization / magnitude
| Function | Generic | Fixed | Strided | Int | Comments |
|-------------|---------|-------|---------|-----|----------------------|
| `limit` | ✓ | | | | |
| `mag` | ✓ | | S2-S4 | | |
| `magSq` | ✓ | 2-4 | S2-S4 | | |
| `normalize` | ✓ | | S2-S4 | | w/ opt target length |
### Distances
| Function | Generic | Fixed | Strided | Int | Comments |
|-----------------------|---------|-------|---------|-----|---------------------|
| `dist` | ✓ | | | | |
| `distSq` | ✓ | 2-4 | | | |
| `distBrayCurtis` | ✓ | | | | |
| `distCanberra` | ✓ | | | | |
| `distChebyshev` | ✓ | 2-4 | | | |
| `distCosine` | ✓ | | | | |
| `distHamming` | ✓ | | | | |
| `distHaversineLatLon` | | 2 | | | lat/lon coordinates |
| `distHaversineLonLat` | | 2 | | | lon/lat coordinates |
| `distJaccard` | ✓ | | | | |
| `distManhattan` | ✓ | 2-4 | | | |
| `distMinkowski` | ✓ | | | | |
| `distSorensenDice` | ✓ | | | | |
| `distWeighted` | ✓ | | | | |
| `pointOnRay` | ✓ | 2-3 | | | point at distance |
### Orientation
| Function | Generic | Fixed | Strided | Int | Comments |
|--------------------|---------|-------|---------|-----|--------------------------|
| `angleBetween` | | 2, 3 | | | |
| `angleRatio` | ✓ | | | | |
| `atan_2` | ✓ | 2-4 | | | `Math.atan2(y, x)` |
| `bisect` | | 2 | | | |
| `cornerBisector` | ✓ | | | | |
| `degrees` | ✓ | 2-4 | | | |
| `direction` | ✓ | | | | normalize(b - a) |
| `faceForward` | ✓ | | | | |
| `heading` | ✓ | | | | alias `headingXY` |
| `headingXY` | ✓ | | | | |
| `headingXZ` | ✓ | | | | |
| `headingYZ` | ✓ | | | | |
| `headingSegment` | ✓ | | | | alias `headingSegmentXY` |
| `headingSegmentXY` | ✓ | | | | |
| `headingSegmentXZ` | ✓ | | | | |
| `headingSegmentYZ` | ✓ | | | | |
| `normalCCW` | | | | | 2D only |
| `normalCW` | | | | | 2D only |
| `perpendicularCCW` | | | | | 2D only |
| `perpendicularCW` | | | | | 2D only |
| `project` | ✓ | | | | |
| `radians` | ✓ | 2-4 | | | |
| `reflect` | ✓ | | | | |
| `refract` | ✓ | | | | |
### Rotations
(Also see rotation matrices provided by
[.ng/matrices](https://github.com/thi-ng/umbrella/tree/develop/packages/matrices))
| Function | Generic | Fixed | Strided | Int | Comments |
|-----------------------|---------|-------|---------|-----|---------------------|
| `rotationAroundAxis` | | 3 | | | |
| `rotationAroundPoint` | | 2 | | | |
| `rotate` | | | S2 | | alias for `rotateZ` |
| `rotateX` | | | S3 | | |
| `rotateY` | | | S3 | | |
| `rotateZ` | | | S3 | | |
### Polar / cartesian conversion
| Function | Generic | Fixed | Strided | Int | Comments |
|-------------|---------|-------|---------|-----|------------|
| `cartesian` | ✓ | 2, 3 | | | 2D/3D only |
| `polar` | ✓ | 2, 3 | | | 2D/3D only |
### Randomness
All ops support custom PRNG impls based on the
[.ng/random](https://github.com/thi-ng/umbrella/tree/develop/packages/random)
`IRandom` interface and use `Math.random` by default:
| Function | Generic | Fixed | Strided | Int | Comments |
|-------------------|---------|-------|---------|-----|----------|
| `jitter` | ✓ | | | | |
| `randMinMax` | ✓ | 2-4 | S2-S4 | | |
| `randNorm` | ✓ | 2-4 | S2-S4 | | |
| `randNormDistrib` | ✓ | 2-4 | S2-S4 | | |
| `random` | ✓ | 2-4 | S2-S4 | | |
| `randomDistrib` | ✓ | 2-4 | S2-S4 | | |
### Unary vector math ops
| Function | Generic | Fixed | Strided | Int | Comments |
|-------------------|---------|-------|---------|-----|--------------------|
| `abs` | ✓ | 2-4 | | | |
| `acos` | ✓ | 2-4 | | | |
| `asin` | ✓ | 2-4 | | | |
| `atan` | ✓ | 2-4 | | | `Math.atan(y / x)` |
| `ceil` | ✓ | 2-4 | | | |
| `cos` | ✓ | 2-4 | | | |
| `cosh` | ✓ | 2-4 | | | |
| `exp` | ✓ | 2-4 | | | |
| `floor` | ✓ | 2-4 | | | |
| `fract` | ✓ | 2-4 | | | |
| `fromHomogeneous` | ✓ | 3, 4 | | | 3D/4D only |
| `invert` | ✓ | 2-4 | | | |
| `invSqrt` | ✓ | 2-4 | | | |
| `isInf` | ✓ | 2-4 | | | |
| `isNaN` | ✓ | 2-4 | | | |
| `log` | ✓ | 2-4 | | | |
| `major` | ✓ | 2-4 | | | |
| `minor` | ✓ | 2-4 | | | |
| `round` | ✓ | 2-4 | | | |
| `sign` | ✓ | 2-4 | | | |
| `sin` | ✓ | 2-4 | | | |
| `sinh` | ✓ | 2-4 | | | |
| `sqrt` | ✓ | 2-4 | | | |
| `sum` | ✓ | 2-4 | | | |
| `tan` | ✓ | 2-4 | | | |
| `trunc` | ✓ | 2-4 | | | |
| `wrap` | ✓ | 2-4 | | | |
### Vector array batch processing
Functions to transform flat / strided buffers w/ vector operations:
- `mapV` / `mapVN` / `mapVV` / `mapVVN` / `mapVVV`
- `mean` / `median`
- `minBounds` / `maxBounds`
### Comparison / equality
- `comparator2` / `comparator3` / `comparator4`
- `equals` / `equals2` / `equals3` / `equals4`
- `eqDelta` / `eqDelta2` / `eqDelta3` / `eqDelta4`
- `eqDeltaS`
- `eqDeltaArray`
### Bitwise operations (int / uint vec)
Arguments are assumed to be signed / unsigned ints. Results will be
forced accordingly.
| Function | Generic | Fixed | Strided | Int | Comments |
|-----------|---------|-------|---------|--------------|----------|
| `bitAnd` | ✓ | | | I2-I4, U2-U4 | |
| `bitAndN` | ✓ | | | I2-I4, U2-U4 | |
| `bitNot` | ✓ | | | I2-I4, U2-U4 | |
| `bitOr` | ✓ | | | I2-I4, U2-U4 | |
| `bitOrN` | ✓ | | | I2-I4, U2-U4 | |
| `bitXor` | ✓ | | | I2-I4, U2-U4 | |
| `bitXorN` | ✓ | | | I2-I4, U2-U4 | |
| `lshift` | ✓ | | | I2-I4, U2-U4 | |
| `rshift` | ✓ | | | I2-I4, U2-U4 | |
| `lshiftN` | ✓ | | | I2-I4, U2-U4 | |
| `rshiftN` | ✓ | | | I2-I4, U2-U4 | |
### Vector conversions / coercions
- `asIVec` (2-4) - signed int vector
- `asUVec` (2-4) - unsigned int vector
- `asBVec` (2-4) - boolean vector
- `fromBVec` (2-4) - coerces each component to 0/1
### Boolean vector logic
| Function | Generic | Fixed | Strided | Int | Comments |
|-------------|---------|-------|---------|-----|-------------------|
| `logicAnd` | ✓ | 2-4 | | | |
| `logicAndN` | ✓ | 2-4 | | | |
| `logicOr` | ✓ | 2-4 | | | |
| `logicOrN` | ✓ | 2-4 | | | |
| `logicNot` | ✓ | 2-4 | | | |
| `every` | ✓ | 2-4 | | | returns `boolean` |
| `some` | ✓ | 2-4 | | | returns `boolean` |
| `not` | ✓ | 2-4 | | | |
### Componentwise comparisons
All resulting in boolean vectors:
| Function | Generic | Fixed | Strided | Int | Comments |
|----------|---------|-------|---------|-----|----------|
| `eq` | ✓ | 2-4 | | | |
| `lt` | ✓ | 2-4 | | | |
| `lte` | ✓ | 2-4 | | | |
| `gt` | ✓ | 2-4 | | | |
| `gte` | ✓ | 2-4 | | | |
| `neq` | ✓ | 2-4 | | | |
### Hashing
- `hash`
### Code generator
- `compile` / `compileG` / `compileGHOF` / `compileHOF`
- `defOp` / `defOpS` / `defFnOp` / `defHofOp`
- `defMathNOp` / `defMathOp`
- `vop`
For more information about the code generator see:
- [emit.ts](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/compile/emit.ts)
- [templates.ts](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/compile/templates.ts)
- [vop.ts](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors/src/vop.ts)
## Authors
- [Karsten Schmidt](https://thi.ng)
If this project contributes to an academic publication, please cite it as:
```bibtex
{thing-vectors,
title = "@thi.ng/vectors",
author = "Karsten Schmidt",
note = "https://thi.ng/vectors",
year = 2015
}
```
## License
© 2015 - 2025 Karsten Schmidt // Apache License 2.0