Skip to content

Instantly share code, notes, and snippets.

@bartwttewaall
Last active June 23, 2022 09:50
Show Gist options
  • Save bartwttewaall/02c998270a88871631568985e542c255 to your computer and use it in GitHub Desktop.
Save bartwttewaall/02c998270a88871631568985e542c255 to your computer and use it in GitHub Desktop.
Bunch of small math methods like clamp and range
export const RAD2DEG = 180 / Math.PI;
export const DEG2RAD = Math.PI / 180;
// compute euclidean modulo of m % n
// https://en.wikipedia.org/wiki/Modulo_operation
export function euclideanModulo(n: number, m: number) {
return ((n % m) + m) % m;
}
export function clamp(value: number, min: number, max: number) {
return Math.max(min, Math.min(value, max));
}
export function clamp01(value: number, min: number, max: number) {
return clamp(normalize(value, min, max), 0, 1);
}
export function wrap(value: number, min: number, max: number) {
const length = max - min;
return ((((value - min) % length) + length) % length) + min;
}
export function wrapLength(value: number, length: number) {
return wrap(value, 0, length);
}
// https://www.desmos.com/calculator/vcsjnyz7x4
export function pingpong(value: number, length = 1) {
return length - Math.abs(euclideanModulo(value, length * 2) - length);
}
export function inRange(value: number, min: number, max: number) {
return value >= Math.min(min, max) && value <= Math.max(min, max);
}
export function normalize(value: number, min: number, max: number) {
if (max - min === 0) throw new Error("Invalid min & max values: would've divided by 0");
return (value - min) / (max - min);
}
// https://en.wikipedia.org/wiki/Linear_interpolation
export function lerp(from: number, to: number, amount: number) {
// guarentees correct result without floating-point arithmetic error
return (1 - amount) * from + amount * to;
}
// https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/
export function inverseLerp(x: number, y: number, value: number) {
return x !== y ? (value - x) / (y - x) : 0;
}
// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/
export function damp(from: number, to: number, lambda: number, dt: number) {
return lerp(from, to, 1 - Math.exp(-lambda * dt));
}
// remap takes a value within a given input range into a given output range
export function remap(iMin: number, iMax: number, oMin: number, oMax: number, value: number) {
return lerp(oMin, oMax, inverseLerp(iMin, iMax, value));
}
// http://en.wikipedia.org/wiki/Smoothstep
export function smoothstep(value: number, min: number, max: number) {
if (value <= min) return 0;
if (value >= max) return 1;
value = (value - min) / (max - min);
return value * value * (3 - 2 * value);
}
export function smootherstep(value: number, min: number, max: number) {
if (value <= min) return 0;
if (value >= max) return 1;
value = (value - min) / (max - min);
return value * value * value * (value * (value * 6 - 15) + 10);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment