mathutil
v5.1.0
Published
Various and random collection of maths utilities
Downloads
10
Maintainers
Readme
mathutil
Collection of utilities vaguely mathematical
Getting started
Install with a node package manager.
npm i -S mathutil
pnpm add mathutil
Collection of useful maths-related utilities. All are dead-code removal friendly so import what you like and be happy that your tree-shaking module can remove everything else. Most utilities are <1kb (gzipped), and importing everything is just over 2kb.
Example
import {lerp} from 'mathutil'
console.log(lerp(10, 15, 0.5))
// 12.5
Individual imports
Each utility is also exposed separately.
import {lerp} from 'mathutil/lerp'
console.log(lerp(0, 10, 0.5))
// 5
Utilities
lerp
(<Number> min, <Number> max, <Float> value) => <Number>
Interpolates value
between the range specified by min
and max
numbers. Value is expected to be in the range 0...1
.
import {lerp} from 'mathutil'
console.log(lerp(0, 20, 0.5))
// 10
toDegrees
(<Number> value) => <Number>
Converts radians into degrees.
import {toDegrees} from 'mathutil'
console.log(toDegrees(Math.PI * 0.5))
// 90
toRadians
(<Number> value) => <Number>
Converts degrees into radians.
import {toDegrees} from 'mathutil'
console.log(toRadians(270))
// 4.71238898038469
### min
(<Array<Number>>|<Set<Number>> set) => <Number>
Returns the lowest value number in a set
import {min} from 'mathutil'
console.log(min([1, 2, 3]))
// 1
console.log(min(new Set([1, 2, 3])))
// 1
max
(<Array<Number>>|<Set<Number>> set) => <Number>
Returns the highest value number in a set
import {max} from 'mathutil'
console.log(max([1, 2, 3]))
// 3
console.log(max(new Set([1, 2, 3])))
// 3
clamp
(<Number> min, <Number> max, <Number> value) => <Number>
Returns the value and ensures it is within the range specified by min
and max
.
import {clamp} from 'mathutil'
console.log(clamp(1, 12, 3))
// 3
console.log(clamp(10, 12.4, 5.4))
// 10
console.log(clamp(1, 4, 100))
// 4
wrap
(<Number> min, <Number> max, <Number> value) => <Number>
Returns the value but translated as if it rotates through the range specified by min
and max
import {wrap} from 'mathutil'
console.log(wrap(0, 4, 6))
// 2
euclidean
(<Array<Number, Number>>, <Array<Number, Number>>) => <Float>
Returns the distance between points a
and b
using the pythagorean theorem.
It involves squaring and rooting so is accurate but isn’t super cheap, if you don’t need the distance but an comparison between distances, consider if using the manhattan distance algorithm would suit (as it is a cheaper equation).
import {euclidean} from 'mathutil'
console.log(euclidean([0, 2], [1, 4]))
// 2.23606797749979
manhattan
(<Array<Number, Number>>, <Array<Number, Number>>) => <Number>
Returns the distance between points a
and b
using the manhattan distance algorithm. This distance calculation is cheaper than using euclidean distance and is appropriate for comparison but may not be appropriate if you specifically need to know the actual distance between two points.
import {manhattan} from 'mathutil'
console.log(manhattan([0, 2], [1, 4]))
// 3
Doom RNG
(seed: number) => () => number
Creates a function that will give you a random integer between 0...255.
This is based on a lookup table which is constructed with the following properties:
- Only numbers between 0 and 255
- Pattern will repeat after you hit index 255
- There are duplicate numbers in the table ∴ there are omissions
- It is deterministic
There are lots of good discussions on how this random number generator works, and it’s quirks, here is one.
It is a little faster than Math.random()
(very roughly, 7% on average, although this wasn’t the most scientific method of testing, try out [/bench/random.js](the benchmark) in different environments).
import {doom} from 'mathutil'
const random = doom()
console.log(random())
// 0...255
You can supply a seed value, this is an index in to the table to start from. The sequence pattern is not affected.
See [#icanhaznumber](this function) for when you absolutely have to have a number right now.
Doom RNG Configurable
A separate function is also exposed to be able to add some configuration to the table lookup.
import {createDoomRng} from 'mathutil/random'
const random = createDoomRng(3, {
table: [0, 1, 2, 3, 4, 5],
range: [1, 4],
})
This configuration starts the seed at offset 3, creates a new small sequential table to pick from, and creates a window that the algorithm will run against (should you want to create lookups from a single larger table, for some reason).
The first couple of iterations (note that the index is incremented before returning an integer):
4, 1, 2, 3, 4, 1
You can also use crypto to fill the table:
import crypto from 'node:crypto'
import {createDoomRng} from 'mathutil/random'
const buffer = new ArrayBuffer(512)
const view = new Uint8Array(buffer)
const random = createDoomRng(0, {
table: crypto.getRandomValues(view),
range: [0, 512],
})
The table
icanhaznumber
When you absolutely positively have to have a number right now...
import {random} from 'mathutil/icanhaznumber.js'
console.log(random())
// 0...255
No configuration options, just numbers in the 0...255 range for you.
So...yeah, it exposes the table and the index variable if you really want to muck with them. You’re in charge, don’t let anyone dictate how you want to live.