# disko:math

> Deterministic scalars, vectors, angles, elementary functions and seeded random numbers.

Import with `import { … } from "disko:math"`. Generated from the module's
shipped declarations. See [Randomness & determinism](/games/randomness) for a
guide.

`disko:math` — deterministic scalars, vectors, angles, elementary functions and seeded random numbers.

Every function is pure and returns bit-identical results on every host. Wrong types throw `TypeError`; invalid values (non-finite numbers, zero vectors, empty arrays, reversed ranges) throw `RangeError`. Error messages name the function and the argument, for example `normalize: vector has zero length`.

Angles are radians. The y axis points down on screen, so a positive rotation turns clockwise on screen.

## Types

### Vector

A point or vector. Other properties on input objects are ignored.

```ts
export interface Vector {
    readonly x: number;
    readonly y: number;
}
```

### Tolerance

Optional absolute tolerance that widens every boundary comparison.

```ts
export interface Tolerance {
    readonly epsilon?: number;
}
```

| Member | Description |
| --- | --- |
| `epsilon` | A finite number >= 0. `0` is the same as omitting it. |

### RandomState

Seeded xoshiro128** state: four uint32 words, never all zero. Frozen.

```ts
export interface RandomState {
    readonly a: number;
    readonly b: number;
    readonly c: number;
    readonly d: number;
}
```

### Draw

One draw: the value and the state to use for the following draw.

```ts
export interface Draw<T> {
    value: T;
    next: RandomState;
}
```

## Constants

### PI

`3.141592653589793`.

```ts
export const PI: number;
```

### TAU

`2 * PI`.

```ts
export const TAU: number;
```

### ZERO

The frozen zero vector `{ x: 0, y: 0 }`.

```ts
export const ZERO: Vector;
```

## Functions

### clamp

Clamps `value` to `[min, max]`.

```ts
export function clamp(value: number, min: number, max: number): number;
```

Throws: RangeError when `min > max`.

### lerp

Linear interpolation `a + (b - a) * t`; `t` is not clamped.

```ts
export function lerp(a: number, b: number, t: number): number;
```

### inverseLerp

The inverse of [`lerp`](#lerp): `(value - a) / (b - a)`.

```ts
export function inverseLerp(a: number, b: number, value: number): number;
```

Throws: RangeError when `a === b`.

### remap

Maps `value` from `[fromMin, fromMax]` onto `[toMin, toMax]`: `lerp(toMin, toMax, inverseLerp(fromMin, fromMax, value))`, unclamped.

```ts
export function remap(value: number, fromMin: number, fromMax: number, toMin: number, toMax: number): number;
```

Throws: RangeError when `fromMin === fromMax`.

### smoothstep

Hermite smoothstep `t² (3 − 2t)` with `t` clamped to `[0, 1]`.

```ts
export function smoothstep(edge0: number, edge1: number, x: number): number;
```

Throws: RangeError when `edge0 === edge1`.

### approxEqual

Whether `|a − b| <= epsilon`. The tolerance is required.

```ts
export function approxEqual(a: number, b: number, epsilon: number): boolean;
```

Throws: RangeError when `epsilon` is negative.

### sin

Sine (FreeBSD msun `s_sin.c`), identical on every host.

```ts
export function sin(x: number): number;
```

### cos

Cosine (FreeBSD msun `s_cos.c`), identical on every host.

```ts
export function cos(x: number): number;
```

### tan

Tangent (FreeBSD msun `s_tan.c`), identical on every host.

```ts
export function tan(x: number): number;
```

### asin

Arcsine in `[−π/2, π/2]` (msun `e_asin.c`).

```ts
export function asin(x: number): number;
```

Throws: RangeError outside `[−1, 1]`.

### acos

Arccosine in `[0, π]` (msun `e_acos.c`).

```ts
export function acos(x: number): number;
```

Throws: RangeError outside `[−1, 1]`.

### atan

Arctangent in `[−π/2, π/2]` (msun `s_atan.c`).

```ts
export function atan(x: number): number;
```

### atan2

Angle of `(x, y)` in `[−π, π]` (msun `e_atan2.c`), with IEEE 754 signed zeros: `atan2(0, -0) === PI`.

```ts
export function atan2(y: number, x: number): number;
```

### exp

`e^x` (msun `e_exp.c`); overflows to `Infinity` above ~709.78.

```ts
export function exp(x: number): number;
```

### log

Natural logarithm (msun `e_log.c`); `log(0) === -Infinity`.

```ts
export function log(x: number): number;
```

Throws: RangeError when `x < 0`.

### log2

Base-2 logarithm (msun `e_log2.c`); `log2(0) === -Infinity`.

```ts
export function log2(x: number): number;
```

Throws: RangeError when `x < 0`.

### pow

`x^y` (msun `e_pow.c`, including its IEEE special cases). Overflows to `±Infinity`, and `pow(±0, y < 0)` is `±Infinity`.

```ts
export function pow(x: number, y: number): number;
```

Throws: RangeError when `x < 0` and `y` is not an integer (a NaN result).

### hypot

`sqrt(x² + y²)` without intermediate overflow or underflow (msun `e_hypot.c`); overflows to `Infinity` only when the result does.

```ts
export function hypot(x: number, y: number): number;
```

### vec

Creates the vector `{ x, y }`.

```ts
export function vec(x: number, y: number): Vector;
```

### add

Component-wise `a + b`.

```ts
export function add(a: Vector, b: Vector): Vector;
```

### sub

Component-wise `a − b`.

```ts
export function sub(a: Vector, b: Vector): Vector;
```

### scale

`v` multiplied by the scalar `s`.

```ts
export function scale(v: Vector, s: number): Vector;
```

### negate

`{ x: −v.x, y: −v.y }`.

```ts
export function negate(v: Vector): Vector;
```

### dot

Dot product `a.x·b.x + a.y·b.y`.

```ts
export function dot(a: Vector, b: Vector): number;
```

### cross

2D cross product `a.x·b.y − a.y·b.x`.

```ts
export function cross(a: Vector, b: Vector): number;
```

### length

Euclidean length `sqrt(x² + y²)`.

```ts
export function length(v: Vector): number;
```

### lengthSquared

Squared length `x² + y²`.

```ts
export function lengthSquared(v: Vector): number;
```

### distance

Euclidean distance between two points.

```ts
export function distance(a: Vector, b: Vector): number;
```

### distanceSquared

Squared distance between two points.

```ts
export function distanceSquared(a: Vector, b: Vector): number;
```

### normalize

The unit vector in the direction of `v`.

```ts
export function normalize(v: Vector): Vector;
```

Throws: RangeError on a zero vector.

### withLength

`v` rescaled to `length` (negative lengths flip it).

```ts
export function withLength(v: Vector, length: number): Vector;
```

Throws: RangeError on a zero vector.

### perpendicular

`{ x: −v.y, y: v.x }`: +90°, clockwise on screen.

```ts
export function perpendicular(v: Vector): Vector;
```

### rotate

`(x·cos − y·sin, x·sin + y·cos)` using the deterministic trigonometry.

```ts
export function rotate(v: Vector, angle: number): Vector;
```

### rotateAround

Rotates `point` around `pivot` by `angle`.

```ts
export function rotateAround(point: Vector, pivot: Vector, angle: number): Vector;
```

### midpoint

The point halfway between `a` and `b`.

```ts
export function midpoint(a: Vector, b: Vector): Vector;
```

### lerpVector

Component-wise [`lerp`](#lerp); `t` is not clamped.

```ts
export function lerpVector(a: Vector, b: Vector, t: number): Vector;
```

### project

The projection of `v` onto the direction of `onto`.

```ts
export function project(v: Vector, onto: Vector): Vector;
```

Throws: RangeError when `onto` is zero.

### reflect

`v` reflected about the line with the given normal, which is normalized internally.

```ts
export function reflect(v: Vector, normal: Vector): Vector;
```

Throws: RangeError when `normal` is zero.

### equals

Exact equality, or each component within `opts.epsilon`.

```ts
export function equals(a: Vector, b: Vector, opts?: Tolerance): boolean;
```

### angleOf

The angle of `v` in `(−π, π]`.

```ts
export function angleOf(v: Vector): number;
```

Throws: RangeError on a zero vector.

### fromAngle

The vector `(cos angle, sin angle) · length`.

```ts
export function fromAngle(angle: number, length?: number): Vector;
```

### normalizeAngle

`angle` wrapped into `(−π, π]`.

```ts
export function normalizeAngle(angle: number): number;
```

### angleDifference

The shortest signed turn from `from` to `to`, in `(−π, π]`.

```ts
export function angleDifference(from: number, to: number): number;
```

### angleBetween

The signed angle from vector `a` to vector `b`, in `(−π, π]`.

```ts
export function angleBetween(a: Vector, b: Vector): number;
```

Throws: RangeError when either vector is zero.

### lerpAngle

Interpolates along the shortest turn; the result is normalized.

```ts
export function lerpAngle(from: number, to: number, t: number): number;
```

### radians

Degrees to radians.

```ts
export function radians(degrees: number): number;
```

### degrees

Radians to degrees.

```ts
export function degrees(radians: number): number;
```

### seed

A random state from a safe integer (its low and high 32 bits) or a string (FNV-1a over its UTF-8 bytes), expanded through splitmix32. The same seed gives the same sequence on every host.

```ts
export function seed(input: number | string): RandomState;
```

Throws: RangeError for a number that is not a safe integer.

### random

A number in `[0, 1)` with 53 random bits (two generator outputs).

```ts
export function random(state: RandomState): Draw<number>;
```

### randomRange

A number in `[min, max)`.

```ts
export function randomRange(state: RandomState, min: number, max: number): Draw<number>;
```

Throws: RangeError when `min >= max` or `max − min` overflows.

### randomInt

An unbiased integer in `[min, max]` (Lemire's method with rejection).

```ts
export function randomInt(state: RandomState, min: number, max: number): Draw<number>;
```

Throws: RangeError unless both are safe integers, `min <= max` and `max − min < 2³²`.

### randomBool

`true` with the given probability in `[0, 1]` (default `0.5`).

```ts
export function randomBool(state: RandomState, probability?: number): Draw<boolean>;
```

Throws: RangeError outside `[0, 1]`.

### pick

One element chosen uniformly.

```ts
export function pick<T>(state: RandomState, array: readonly T[]): Draw<T>;
```

Throws: RangeError on an empty array.

### shuffle

A new array shuffled with Fisher–Yates; the input is untouched.

```ts
export function shuffle<T>(state: RandomState, array: readonly T[]): Draw<T[]>;
```

### fork

An independent child state seeded through splitmix32 from two parent outputs; `next` continues the parent.

```ts
export function fork(state: RandomState): Draw<RandomState>;
```
