Skip to content

Instantly share code, notes, and snippets.

@intoxopox
Last active October 16, 2018 02:08
Show Gist options
  • Save intoxopox/94a23b85e8196b09f4dcba1199ca4123 to your computer and use it in GitHub Desktop.
Save intoxopox/94a23b85e8196b09f4dcba1199ca4123 to your computer and use it in GitHub Desktop.
MathUtil - Handy math functions
////////////////////////////////////////////////////////////////////////////////
// Copyright(C) 2018 David Hamiter
////////////////////////////////////////////////////////////////////////////////
'use strict';
/**
* @author David Hamiter
* Static class for math beyond built-in Math class or replacing existing Math class methods with faster implementations.
*/
export default abstract class MathUtil {
//----------------------------------------------------------------------
//
// Properties
//
//----------------------------------------------------------------------
static readonly PI:number = Math.PI;
static readonly HALF_PI: number = MathUtil.PI * .5;
static readonly PI_AND_Half: number = MathUtil.HALF_PI + MathUtil.PI;
static readonly TWICE_PI: number = MathUtil.PI + MathUtil.PI;
static readonly BIG_INT:number = 0xffffff;
/**
* Multiply an angle in degrees by this number to convert to radians.
*/
static readonly TO_RADIAN: number = MathUtil.PI / 180;
/**
* Multiply an angle in radians by this number to convert to degrees.
*/
static readonly TO_DEGREE: number = 180 / MathUtil.PI;
//----------------------------------------------------------------------
//
// Constructor
//
//----------------------------------------------------------------------
private constructor() { } // Static class cannot be instantiated
//----------------------------------------------------------------------
//
// Methods
//
//----------------------------------------------------------------------
/**
* Returns absolute value... about 20x faster than Math.abs
*/
static abs(value:number):number {
return value < 0 ? -value : value;
}
/**
* Returns ceiling... about 50% faster than Math.ceil.
*/
static function ceil(value:number):number {
return (value % 1 > 0) ? value + 1 : value;
}
/**
* Returns the Radians of a given angle in degrees.
*/
static degToRad(ang:number):number {
return ang * MathUtil.TO_RADIAN;
}
/**
* Returns the Degrees of a given radian angle.
*/
static radToDeg(rad:number):number {
return rad * MathUtil.TO_DEGREE;
}
/**
* Returns the angle between two objects. "Rads" toggles if it returns radians or degrees.
*/
static angle(X1:number, Y1:number, X2:number, Y2:number, Rads?:boolean):number {
const rads:number = Math.atan2(Y2 - Y1, X2 - X1);
return (Rads) ? rads : rads * MathUtil.TO_DEGREE;
}
static standardAngle(X1:number, Y1:number, X2:number, Y2:number):number {
var ang: number = Math.atan2(Y2 - Y1, X2 - X1) * MathUtil.TO_DEGREE;
const a:number = 360 - (((ang %= 360)<0) ? ang+360 : ang);
return (a == 360) ? 0 : a;
}
static radialToPoint(length:number, angle:number):{x:number, y:number} {
var radians:number = angle * TO_RADIAN;
return {x:length * Math.cos(radians) + .5, y:length * Math.sin(radians) + .5);
}
/**
* Returns the distance between two objects.
*/
static dist(X1:number, Y1:number, X2:number, Y2:number):number {
const dX:number = X2 - X1;
const dY:number = Y2 - Y1;
return Math.sqrt(dX * dX + dY * dY);
}
/**
* Returns true if number given is odd.
*/
static isOdd(n:number):boolean {
return !!(n & 1);
}
/**
* Returns true if "a" is divisible by "b".
*/
static isDivisible(a:number, b:number):boolean {
return !(a % b);
}
/**
* Returns the greatest common denominator of a and b.
* @param a
* @param b
* @return
*/
static gdc(a:number, b:number):number {
var r:number;
while (b != 0) {
r = a % b;
a = b;
b = r;
}
return (a < 0) ? -a : a;
}
/**
* Returns the least common multiple of a and b.
* @param a
* @param b
* @return
*/
static lcm(a:number, b:number):number {
if (a == 0 || b == 0) return 0;
var t:number;
var prod = a * b;
while (b != 0) {
t = b;
b = a % t;
a = t;
}
return Math.abs(prod / a);
}
/**
* Returns average of any number of coma seperated arguments or array or arguments.
*/
static average(...nums: number[]):number {
if (nums && nums.length) {
var i: number = nums.length;
var j: number = i;
var sum: number = 0;
while (i--) sum += nums[i];
return sum / j;
}
return NaN;
}
/**
* Returns what percentage "a" is of "b".
*/
static percent(a: number, b: number): number {
return a / b * 100;
}
/**
* Returns a random number between "a" and "b".
*/
static randomBetween(a: number, b: number, float?: boolean): number {
const hi: number = (a > b) ? a: b;
const lo: number = (a < b) ? a: b;
return float ? lo + Math.random() * MathUtil.abs(hi - lo) : lo + Math.round(Math.random() * MathUtil.abs(hi - lo));
}
/**
* Returns a random number "numDigits" long.
* @param numDigits
*/
static randomXDigits(numDigits: number):number {
var base = Math.pow(10, numDigits - 1);
return Math.floor(base + Math.random() * (base * 9));
}
/**
* Returns value after clipping it to be at least min and no greater than max.
* @param value
* @param min
* @param max
*/
static rangeClip(value: number, min: number, max: number): number {
return value < min ? min : value > max ? max : value;
}
/**
* Returns number rounded to a given decimal place.
*/
static roundTo(num: number, place: number): number {
const p: number = Math.pow(10, place);
return Math.round(num * p) / p;
}
/**
* Returns the n root of a given number.
*/
static nrt(num: number, n: number): number {
return Math.pow(num, 1 / n);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment