Files
Foundry-VTT-Docker/resources/app/common/primitives/math.mjs
2025-01-04 00:34:03 +01:00

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
}
});