166 lines
4.4 KiB
JavaScript
166 lines
4.4 KiB
JavaScript
|
|
/**
|
||
|
|
* √3
|
||
|
|
* @type {number}
|
||
|
|
*/
|
||
|
|
export const SQRT3 = 1.7320508075688772;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* √⅓
|
||
|
|
* @type {number}
|
||
|
|
*/
|
||
|
|
export const SQRT1_3 = 0.5773502691896257;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Bound a number between some minimum and maximum value, inclusively.
|
||
|
|
* @param {number} num The current value
|
||
|
|
* @param {number} min The minimum allowed value
|
||
|
|
* @param {number} max The maximum allowed value
|
||
|
|
* @return {number} The clamped number
|
||
|
|
* @memberof Math
|
||
|
|
*/
|
||
|
|
export function clamp(num, min, max) {
|
||
|
|
return Math.min(Math.max(num, min), max);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @deprecated since v12
|
||
|
|
* @ignore
|
||
|
|
*/
|
||
|
|
export function clamped(num, min, max) {
|
||
|
|
const msg = "Math.clamped is deprecated in favor of Math.clamp.";
|
||
|
|
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
|
||
|
|
return clamp(num, min, max);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Linear interpolation function
|
||
|
|
* @param {number} a An initial value when weight is 0.
|
||
|
|
* @param {number} b A terminal value when weight is 1.
|
||
|
|
* @param {number} w A weight between 0 and 1.
|
||
|
|
* @return {number} The interpolated value between a and b with weight w.
|
||
|
|
*/
|
||
|
|
export function mix(a, b, w) {
|
||
|
|
return a * (1 - w) + b * w;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Transform an angle in degrees to be bounded within the domain [0, 360)
|
||
|
|
* @param {number} degrees An angle in degrees
|
||
|
|
* @returns {number} The same angle on the range [0, 360)
|
||
|
|
*/
|
||
|
|
export function normalizeDegrees(degrees, base) {
|
||
|
|
const d = degrees % 360;
|
||
|
|
if ( base !== undefined ) {
|
||
|
|
const msg = "Math.normalizeDegrees(degrees, base) is deprecated.";
|
||
|
|
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
|
||
|
|
if ( base === 360 ) return d <= 0 ? d + 360 : d;
|
||
|
|
}
|
||
|
|
return d < 0 ? d + 360 : d;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Transform an angle in radians to be bounded within the domain [-PI, PI]
|
||
|
|
* @param {number} radians An angle in degrees
|
||
|
|
* @return {number} The same angle on the range [-PI, PI]
|
||
|
|
*/
|
||
|
|
export function normalizeRadians(radians) {
|
||
|
|
const pi = Math.PI;
|
||
|
|
const pi2 = pi * 2;
|
||
|
|
return radians - (pi2 * Math.floor((radians + pi) / pi2));
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @deprecated since v12
|
||
|
|
* @ignore
|
||
|
|
*/
|
||
|
|
export function roundDecimals(number, places) {
|
||
|
|
const msg = "Math.roundDecimals is deprecated.";
|
||
|
|
foundry.utils.logCompatibilityWarning(msg, {since: 12, until: 14, once: true});
|
||
|
|
places = Math.max(Math.trunc(places), 0);
|
||
|
|
let scl = Math.pow(10, places);
|
||
|
|
return Math.round(number * scl) / scl;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Transform an angle in radians to a number in degrees
|
||
|
|
* @param {number} angle An angle in radians
|
||
|
|
* @return {number} An angle in degrees
|
||
|
|
*/
|
||
|
|
export function toDegrees(angle) {
|
||
|
|
return angle * (180 / Math.PI);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Transform an angle in degrees to an angle in radians
|
||
|
|
* @param {number} angle An angle in degrees
|
||
|
|
* @return {number} An angle in radians
|
||
|
|
*/
|
||
|
|
export function toRadians(angle) {
|
||
|
|
return angle * (Math.PI / 180);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the value of the oscillation between `a` and `b` at time `t`.
|
||
|
|
* @param {number} a The minimium value of the oscillation
|
||
|
|
* @param {number} b The maximum value of the oscillation
|
||
|
|
* @param {number} t The time
|
||
|
|
* @param {number} [p=1] The period (must be nonzero)
|
||
|
|
* @param {(x: number) => number} [f=Math.cos] The periodic function (its period must be 2π)
|
||
|
|
* @returns {number} `((b - a) * (f(2π * t / p) + 1) / 2) + a`
|
||
|
|
*/
|
||
|
|
export function oscillation(a, b, t, p=1, f=Math.cos) {
|
||
|
|
return ((b - a) * (f((2 * Math.PI * t) / p) + 1) / 2) + a;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Define properties on the Math environment
|
||
|
|
Object.defineProperties(Math, {
|
||
|
|
SQRT3: {value: SQRT3},
|
||
|
|
SQRT1_3: {value: SQRT1_3},
|
||
|
|
clamp: {
|
||
|
|
value: clamp,
|
||
|
|
configurable: true,
|
||
|
|
writable: true
|
||
|
|
},
|
||
|
|
clamped: {
|
||
|
|
value: clamped,
|
||
|
|
configurable: true,
|
||
|
|
writable: true
|
||
|
|
},
|
||
|
|
mix: {
|
||
|
|
value: mix,
|
||
|
|
configurable: true,
|
||
|
|
writable: true
|
||
|
|
},
|
||
|
|
normalizeDegrees: {
|
||
|
|
value: normalizeDegrees,
|
||
|
|
configurable: true,
|
||
|
|
writable: true
|
||
|
|
},
|
||
|
|
normalizeRadians: {
|
||
|
|
value: normalizeRadians,
|
||
|
|
configurable: true,
|
||
|
|
writable: true
|
||
|
|
},
|
||
|
|
roundDecimals: {
|
||
|
|
value: roundDecimals,
|
||
|
|
configurable: true,
|
||
|
|
writable: true
|
||
|
|
},
|
||
|
|
toDegrees: {
|
||
|
|
value: toDegrees,
|
||
|
|
configurable: true,
|
||
|
|
writable: true
|
||
|
|
},
|
||
|
|
toRadians: {
|
||
|
|
value: toRadians,
|
||
|
|
configurable: true,
|
||
|
|
writable: true
|
||
|
|
},
|
||
|
|
oscillation: {
|
||
|
|
value: oscillation,
|
||
|
|
configurable: true,
|
||
|
|
writable: true
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|