"use strict";
/**
* @module extendedMath
*/
var extendedMath = { };
function isInvalidNumber(value) {
return typeof value !== "number" || isNaN(value) || value === -Infinity || value === Infinity;
}
/**
* A static constant number representing 1/2 of PI.
*
* @constant {number} HalfPI=1.57079632679489661923
* @since 1.0.0
* @memberOf module:extendedMath
*/
Object.defineProperty(extendedMath, "HalfPI", {
value: 1.57079632679489661923,
enumerable: true
});
/**
* A static constant number representing 1/4 of PI.
*
* @constant {number} QuarterPI=0.78539816339744830962
* @since 1.0.0
* @memberOf module:extendedMath
*/
Object.defineProperty(extendedMath, "QuarterPI", {
value: 0.78539816339744830962,
enumerable: true
});
/**
* A static constant number representing 2x PI.
*
* @constant {number} TwoPI=6.28318530717958647693
* @since 1.0.0
* @memberOf module:extendedMath
*/
Object.defineProperty(extendedMath, "TwoPI", {
value: 6.28318530717958647693,
enumerable: true
});
/**
* Clamps a number between a minimum and maximum value.
* +/- Infinity are not valid minimum / maximum values.
*
* @function clamp
* @param {number} value - The number to clamp.
* @param {number} min - The minimum number to clamp to.
* @param {number} max - The maximum number to clamp to.
* @returns {number} A value which is inclusively adjusted between the specified mimum and maximum values, or NaN if any arguments are not valid numbers.
* @since 1.0.0
* @memberOf module:extendedMath
* @example
* console.log(extendedMath.clamp(3.141592654, -1, 3)); // 3
* console.log(extendedMath.clamp(-1.337, -4.2, 6.9)); // -1.337
* console.log(extendedMath.clamp(-800, -2.8, 1)); // -2.8
* console.log(extendedMath.clamp(1, 2, Infinity)); // NaN
* console.log(extendedMath.clamp(1, -Infinity, 4)); // NaN
* console.log(extendedMath.clamp(Infinity, 0, 1)); // NaN
*/
extendedMath.clamp = function clamp(value, min, max) {
return isInvalidNumber(value) || isInvalidNumber(min) || isInvalidNumber(max) ? NaN : value < min ? min : value > max ? max : value;
};
/**
* Calculates the positive difference between two numbers.
* Values must be valid finite numbers.
*
* @function difference
* @param {number} a - The first number.
* @param {number} b - The second number.
* @returns {number} A positive value representing the difference between two numbers, or NaN if either argument is not a valid number.
* @since 1.0.8
* @memberOf module:extendedMath
* @example
* console.log(extendedMath.difference(3, 9)); // 6
* console.log(extendedMath.difference(4, -4)); // 8
* console.log(extendedMath.difference(Infinity, 4)); // NaN
* console.log(extendedMath.difference(NaN, 8080)); // NaN
*/
extendedMath.difference = function difference(a, b) {
return isInvalidNumber(a) || isInvalidNumber(b) ? NaN : Math.abs(b - a);
};
/**
* Calculates the positive distance between two numbers.
*
* @function distance
* @param {number} a - The first number.
* @param {number} b - The second number.
* @returns {number} A positive value representing the distance between two numbers, or NaN if either argument is not a valid number.
* @deprecated Renamed to difference so the unit context of the values is not assumed.
* @see {@link module:extendedMath.difference|difference}
* @since 1.0.0
* @memberOf module:extendedMath
* @example
* console.log(extendedMath.distance(3, 9)); // 6
* console.log(extendedMath.distance(4, -4)); // 8
* console.log(extendedMath.distance(Infinity, 4)); // NaN
* console.log(extendedMath.distance(NaN, 8080)); // NaN
*/
extendedMath.distance = extendedMath.difference;
/**
* Converts an angle value in radians to degrees.
*
* @function radiansToDegrees
* @param {number} value - An angle value represented in radians.
* @returns {number} A value representing the angle in degrees instead of radians, or NaN if the argument is not a valid number.
* @since 1.0.0
* @memberOf module:extendedMath
* @example
* console.log(extendedMath.radiansToDegrees(Math.PI * 2)); // 360
* console.log(extendedMath.radiansToDegrees(Math.PI / 2)); // 90
* console.log(extendedMath.radiansToDegrees(-Infinity)); // NaN
* console.log(extendedMath.radiansToDegrees(NaN)); // NaN
*/
extendedMath.radiansToDegrees = function radiansToDegrees(value) {
return isInvalidNumber(value) ? NaN : value * (180 / Math.PI);
};
/**
* Converts an angle value in degrees to radians.
*
* @function degreesToRadians
* @param {number} value - An angle value represented in degrees.
* @returns {number} A value representing the angle in radians instead of degrees, or NaN if the argument is not a valid number.
* @since 1.0.0
* @memberOf module:extendedMath
* @example
* console.log(extendedMath.degreesToRadians(360)); // 6.283185307179586
* console.log(extendedMath.degreesToRadians(180)); // 3.141592653589793
* console.log(extendedMath.degreesToRadians(Infinity)); // NaN
* console.log(extendedMath.degreesToRadians(NaN)); // NaN
*/
extendedMath.degreesToRadians = function degreesToRadians(value) {
return isInvalidNumber(value) ? NaN : value * (Math.PI / 180);
};
/**
* Performs a comparison on two angles represented in degrees.
* If an angle is less than 0 or greater than 360, it is transformed so that it is within this scale before comparing.
*
* @function compareAnglesDegrees
* @param {a} value - An angle value represented in degrees.
* @param {b} value - Another angle value represented in degrees to compare against.
* @returns {number} A value of 0 if the .angles are equal, 1 if the first angle is to the left of the second angle, or -1 if the first angle is to the right of the second angle. If any arguments are not valid numbers, then NaN is returned instead.
* @since 1.0.0
* @memberOf module:extendedMath
* @example
* console.log(extendedMath.compareAnglesDegrees(0, 360)); // 0
* console.log(extendedMath.compareAnglesDegrees(-90, 90)); // 1
* console.log(extendedMath.compareAnglesDegrees(120, 30)); // -1
* console.log(extendedMath.compareAnglesDegrees(-Infinity, 1)); // NaN
* console.log(extendedMath.compareAnglesDegrees(-2, NaN)); // NaN
*/
extendedMath.compareAnglesDegrees = function compareAnglesDegrees(a, b) {
if(isInvalidNumber(a) || isInvalidNumber(b)) {
return NaN;
}
if(a === b) {
return 0;
}
var c = a % 360;
var d = b % 360;
if(c < 0) {
c += 360;
}
if(d < 0) {
d += 360;
}
if(c === d) {
return 0;
}
return Math.cos(extendedMath.degreesToRadians(a - b) + (Math.PI / 2)) < 0 ? -1 : 1;
};
/**
* Performs a comparison on two angles represented in radians.
* If an angle is less than 0 or greater than 360, it is transformed so that it is within this scale before comparing.
*
* @function compareAnglesRadians
* @param {a} value - An angle value represented in radians.
* @param {b} value - Another angle value represented in radians to compare against.
* @returns {number} A value of 0 if the .angles are equal, 1 if the first angle is to the left of the second angle, or -1 if the first angle is to the right of the second angle. If any arguments are not valid numbers, then NaN is returned instead.
* @since 1.0.0
* @memberOf module:extendedMath
* @example
* console.log(extendedMath.compareAnglesRadians(0, Math.PI * 2)); // 0
* console.log(extendedMath.compareAnglesRadians(-(Math.PI / 2), Math.PI / 2)); // 1
* console.log(extendedMath.compareAnglesRadians(2 * (Math.PI / 3), (Math.PI / 3))); // -1
* console.log(extendedMath.compareAnglesRadians(-Infinity, 1)); // NaN
* console.log(extendedMath.compareAnglesRadians(-2, NaN)); // NaN
*/
extendedMath.compareAnglesRadians = function compareAnglesRadians(a, b) {
return isInvalidNumber(a) || isInvalidNumber(b) ? NaN : extendedMath.compareAnglesDegrees(extendedMath.radiansToDegrees(a), extendedMath.radiansToDegrees(b));
};
/**
* Linerarly interpolates between two numbers relative to a multiplier value.
*
* @function lerp
* @param {number} a - The low end of the interpolation scale.
* @param {number} b - The high end of the interpolation scale.
* @param {number} amount - The multiplier number to interpolate by.
* @returns {number} A number interpolated relative to the low and high end numbers, or NaN if any of the arguments are not valid numbers.
* @since 1.0.0
* @memberOf module:extendedMath
* @example
* console.log(extendedMath.lerp(0, 1.5, 2)); // 3
* console.log(extendedMath.lerp(-4, 8, 0.5)); // 2
* console.log(extendedMath.lerp(0.5, 1.5, 0.75)); // 1.25
* console.log(extendedMath.lerp(0, 1, Infinity)); // NaN
* console.log(extendedMath.lerp(NaN, 320, 240)); // NaN
*/
extendedMath.lerp = function lerp(a, b, amount) {
if(isInvalidNumber(a) || isInvalidNumber(b) || isInvalidNumber(amount)) {
return NaN;
}
if(amount === 0) {
return a;
}
else if(amount === 1) {
return b;
}
return a + ((b - a) * amount);
};
/**
* Normalizes a number based on a min and max value.
*
* @function normalize
* @param {number} value - The number to normalize.
* @param {number} min - The low end number to normalize relative to.
* @param {number} max - The high end number to normalize relative to.
* @returns {number} A number normalized relative to the low and high end values, or NaN if any of the arguments are not valid numbers.
* @since 1.0.0
* @memberOf module:extendedMath
* @example
* console.log(extendedMath.normalize(1, 0, 2)); // 0.5
* console.log(extendedMath.normalize(4, 1, 5)); // 0.75
* console.log(extendedMath.normalize(-3, -4, 0)); // 0.25
* console.log(extendedMath.normalize(16, 0, 4)); // 4
* console.log(extendedMath.normalize(NaN, 0, 1)); // NaN
* console.log(extendedMath.normalize(1, -Infinity, 2)); // NaN
*/
extendedMath.normalize = function normalize(value, min, max) {
return isInvalidNumber(value) || isInvalidNumber(min) || isInvalidNumber(max) ? NaN : (value - min) / (max - min);
};
module.exports = extendedMath;