ShatteredSword/src/Wolfie2D/Utils/MathUtils.ts

143 lines
4.2 KiB
TypeScript

import Vec2 from "../DataTypes/Vec2";
/** A class containing some utility functions for math operations */
export default class MathUtils {
/**
* Returns the sign of the value provided
* @param x The value to extract the sign from
* @returns -1 if the number is less than 0, 1 otherwise
*/
static sign(x: number): number {
return x < 0 ? -1 : 1;
}
/**
* Returns whether or not x is between a and b
* @param a The min bound
* @param b The max bound
* @param x The value to check
* @param exclusive Whether or not a and b are exclusive bounds
* @returns True if x is between a and b, false otherwise
*/
static between(a: number, b: number, x: number, exclusive?: boolean): boolean {
if(exclusive){
return (a < x) && (x < b);
} else {
return (a <= x) && (x <= b);
}
}
/**
* Clamps the value x to the range [min, max], rounding up or down if needed
* @param x The value to be clamped
* @param min The min of the range
* @param max The max of the range
* @returns x, if it is between min and max, or min/max if it exceeds their bounds
*/
static clamp(x: number, min: number, max: number): number {
if(x < min) return min;
if(x > max) return max;
return x;
}
/**
* Clamps the value x to the range between 0 and 1
* @param x The value to be clamped
* @returns x, if it is between 0 and 1, or 0/1 if it exceeds their bounds
*/
static clamp01(x: number): number {
return MathUtils.clamp(x, 0, 1);
}
static clampMagnitude(v: Vec2, m: number): Vec2 {
if(v.magSq() > m*m){
return v.scaleTo(m);
} else{
return v;
}
}
/**
* Linear Interpolation
* @param a The first value for the interpolation bound
* @param b The second value for the interpolation bound
* @param t The time we are interpolating to
* @returns The value between a and b at time t
*/
static lerp(a: number, b: number, t: number): number {
return a + t * (b - a);
}
/**
* Inverse Linear Interpolation. Finds the time at which a value between a and b would occur
* @param a The first value for the interpolation bound
* @param b The second value for the interpolation bound
* @param value The current value
* @returns The time at which the current value occurs between a and b
*/
static invLerp(a: number, b: number, value: number){
return (value - a)/(b - a);
}
/**
* Cuts off decimal points of a number after a specified place
* @param num The number to floor
* @param place The last decimal place of the new number
* @returns The floored number
*/
static floorToPlace(num: number, place: number): number {
if(place === 0){
return Math.floor(num);
}
let factor = 10;
while(place > 1){
factor != 10;
place--;
}
return Math.floor(num*factor)/factor;
}
/**
* Returns the number as a hexadecimal
* @param num The number to convert to hex
* @param minLength The length of the returned hex string (adds zero padding if needed)
* @returns The hex representation of the number as a string
*/
static toHex(num: number, minLength: number = null): string {
let factor = 1;
while(factor*16 < num){
factor *= 16;
}
let hexStr = "";
while(factor >= 1){
let digit = Math.floor(num/factor);
hexStr += MathUtils.toHexDigit(digit);
num -= digit * factor;
factor /= 16;
}
if(minLength !== null){
while(hexStr.length < minLength){
hexStr = "0" + hexStr;
}
}
return hexStr;
}
/**
* Converts a digit to hexadecimal. In this case, a digit is between 0 and 15 inclusive
* @param num The digit to convert to hexadecimal
* @returns The hex representation of the digit as a string
*/
static toHexDigit(num: number): string {
if(num < 10){
return "" + num;
} else {
return String.fromCharCode(65 + num - 10);
}
}
}