@babylonjs/core
Version:
Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.
339 lines • 11.1 kB
JavaScript
/**
* Extract int value
* @param value number value
* @returns int value
*/
export function ExtractAsInt(value) {
return parseInt(value.toString().replace(/\W/g, ""));
}
/**
* Boolean : true if the absolute difference between a and b is lower than epsilon (default = 1.401298E-45)
* @param a number
* @param b number
* @param epsilon (default = 1.401298E-45)
* @returns true if the absolute difference between a and b is lower than epsilon (default = 1.401298E-45)
*/
export function WithinEpsilon(a, b, epsilon = 1.401298e-45) {
return Math.abs(a - b) <= epsilon;
}
/**
* Boolean : true if the number is outside a range
* @param num number
* @param min min value
* @param max max value
* @param epsilon (default = Number.EPSILON)
* @returns true if the number is between min and max values
*/
export function OutsideRange(num, min, max, epsilon = 1.401298e-45) {
return num < min - epsilon || num > max + epsilon;
}
/**
* Returns a random float number between and min and max values
* @param min min value of random
* @param max max value of random
* @returns random value
*/
export function RandomRange(min, max) {
if (min === max) {
return min;
}
return Math.random() * (max - min) + min;
}
/**
* Creates a new scalar with values linearly interpolated of "amount" between the start scalar and the end scalar.
* @param start start value
* @param end target value
* @param amount amount to lerp between
* @returns the lerped value
*/
export function Lerp(start, end, amount) {
return start + (end - start) * amount;
}
/**
* Same as Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees.
* The parameter t is clamped to the range [0, 1]. Variables a and b are assumed to be in degrees.
* @param start start value
* @param end target value
* @param amount amount to lerp between
* @returns the lerped value
*/
export function LerpAngle(start, end, amount) {
let num = Repeat(end - start, 360.0);
if (num > 180.0) {
num -= 360.0;
}
return start + num * Clamp(amount);
}
/**
* Calculates the linear parameter t that produces the interpolant value within the range [a, b].
* @param a start value
* @param b target value
* @param value value between a and b
* @returns the inverseLerp value
*/
export function InverseLerp(a, b, value) {
let result;
if (a != b) {
result = Clamp((value - a) / (b - a));
}
else {
result = 0.0;
}
return result;
}
/**
* Returns a new scalar located for "amount" (float) on the Hermite spline defined by the scalars "value1", "value3", "tangent1", "tangent2".
* @see http://mathworld.wolfram.com/HermitePolynomial.html
* @param value1 defines the first control point
* @param tangent1 defines the first tangent
* @param value2 defines the second control point
* @param tangent2 defines the second tangent
* @param amount defines the amount on the interpolation spline (between 0 and 1)
* @returns hermite result
*/
export function Hermite(value1, tangent1, value2, tangent2, amount) {
const squared = amount * amount;
const cubed = amount * squared;
const part1 = 2.0 * cubed - 3.0 * squared + 1.0;
const part2 = -2.0 * cubed + 3.0 * squared;
const part3 = cubed - 2.0 * squared + amount;
const part4 = cubed - squared;
return value1 * part1 + value2 * part2 + tangent1 * part3 + tangent2 * part4;
}
/**
* Returns a new scalar which is the 1st derivative of the Hermite spline defined by the scalars "value1", "value2", "tangent1", "tangent2".
* @param value1 defines the first control point
* @param tangent1 defines the first tangent
* @param value2 defines the second control point
* @param tangent2 defines the second tangent
* @param time define where the derivative must be done
* @returns 1st derivative
*/
export function Hermite1stDerivative(value1, tangent1, value2, tangent2, time) {
const t2 = time * time;
return (t2 - time) * 6 * value1 + (3 * t2 - 4 * time + 1) * tangent1 + (-t2 + time) * 6 * value2 + (3 * t2 - 2 * time) * tangent2;
}
/**
* Returns the value itself if it's between min and max.
* Returns min if the value is lower than min.
* Returns max if the value is greater than max.
* @param value the value to clmap
* @param min the min value to clamp to (default: 0)
* @param max the max value to clamp to (default: 1)
* @returns the clamped value
*/
export function Clamp(value, min = 0, max = 1) {
return Math.min(max, Math.max(min, value));
}
/**
* Returns the angle converted to equivalent value between -Math.PI and Math.PI radians.
* @param angle The angle to normalize in radian.
* @returns The converted angle.
*/
export function NormalizeRadians(angle) {
// More precise but slower version kept for reference.
// angle = angle % Tools.TwoPi;
// angle = (angle + Tools.TwoPi) % Tools.TwoPi;
//if (angle > Math.PI) {
// angle -= Tools.TwoPi;
//}
angle -= Math.PI * 2 * Math.floor((angle + Math.PI) / (Math.PI * 2));
return angle;
}
/**
* Returns a string : the upper case translation of the number i to hexadecimal.
* @param i number
* @returns the upper case translation of the number i to hexadecimal.
*/
export function ToHex(i) {
const str = i.toString(16);
if (i <= 15) {
return ("0" + str).toUpperCase();
}
return str.toUpperCase();
}
/**
* the floor part of a log2 value.
* @param value the value to compute log2 of
* @returns the log2 of value.
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
export function ILog2(value) {
if (Math.log2) {
return Math.floor(Math.log2(value));
}
if (value < 0) {
return NaN;
}
else if (value === 0) {
return -Infinity;
}
let n = 0;
if (value < 1) {
while (value < 1) {
n++;
value = value * 2;
}
n = -n;
}
else if (value > 1) {
while (value > 1) {
n++;
value = Math.floor(value / 2);
}
}
return n;
}
/**
* Loops the value, so that it is never larger than length and never smaller than 0.
*
* This is similar to the modulo operator but it works with floating point numbers.
* For example, using 3.0 for t and 2.5 for length, the result would be 0.5.
* With t = 5 and length = 2.5, the result would be 0.0.
* Note, however, that the behaviour is not defined for negative numbers as it is for the modulo operator
* @param value the value
* @param length the length
* @returns the looped value
*/
export function Repeat(value, length) {
return value - Math.floor(value / length) * length;
}
/**
* Normalize the value between 0.0 and 1.0 using min and max values
* @param value value to normalize
* @param min max to normalize between
* @param max min to normalize between
* @returns the normalized value
*/
export function Normalize(value, min, max) {
return (value - min) / (max - min);
}
/**
* Denormalize the value from 0.0 and 1.0 using min and max values
* @param normalized value to denormalize
* @param min max to denormalize between
* @param max min to denormalize between
* @returns the denormalized value
*/
export function Denormalize(normalized, min, max) {
return normalized * (max - min) + min;
}
/**
* Calculates the shortest difference between two given angles given in degrees.
* @param current current angle in degrees
* @param target target angle in degrees
* @returns the delta
*/
export function DeltaAngle(current, target) {
let num = Repeat(target - current, 360.0);
if (num > 180.0) {
num -= 360.0;
}
return num;
}
/**
* PingPongs the value t, so that it is never larger than length and never smaller than 0.
* @param tx value
* @param length length
* @returns The returned value will move back and forth between 0 and length
*/
export function PingPong(tx, length) {
const t = Repeat(tx, length * 2.0);
return length - Math.abs(t - length);
}
/**
* Interpolates between min and max with smoothing at the limits.
*
* This function interpolates between min and max in a similar way to Lerp. However, the interpolation will gradually speed up
* from the start and slow down toward the end. This is useful for creating natural-looking animation, fading and other transitions.
* @param from from
* @param to to
* @param tx value
* @returns the smooth stepped value
*/
export function SmoothStep(from, to, tx) {
let t = Clamp(tx);
t = -2.0 * t * t * t + 3.0 * t * t;
return to * t + from * (1.0 - t);
}
/**
* Moves a value current towards target.
*
* This is essentially the same as Mathf.Lerp but instead the function will ensure that the speed never exceeds maxDelta.
* Negative values of maxDelta pushes the value away from target.
* @param current current value
* @param target target value
* @param maxDelta max distance to move
* @returns resulting value
*/
export function MoveTowards(current, target, maxDelta) {
let result;
if (Math.abs(target - current) <= maxDelta) {
result = target;
}
else {
result = current + Math.sign(target - current) * maxDelta;
}
return result;
}
/**
* Same as MoveTowards but makes sure the values interpolate correctly when they wrap around 360 degrees.
*
* Variables current and target are assumed to be in degrees. For optimization reasons, negative values of maxDelta
* are not supported and may cause oscillation. To push current away from a target angle, add 180 to that angle instead.
* @param current current value
* @param target target value
* @param maxDelta max distance to move
* @returns resulting angle
*/
export function MoveTowardsAngle(current, target, maxDelta) {
const num = DeltaAngle(current, target);
let result;
if (-maxDelta < num && num < maxDelta) {
result = target;
}
else {
target = current + num;
result = MoveTowards(current, target, maxDelta);
}
return result;
}
/**
* This function returns percentage of a number in a given range.
*
* RangeToPercent(40,20,60) will return 0.5 (50%)
* RangeToPercent(34,0,100) will return 0.34 (34%)
* @param number to convert to percentage
* @param min min range
* @param max max range
* @returns the percentage
*/
export function RangeToPercent(number, min, max) {
return (number - min) / (max - min);
}
/**
* This function returns number that corresponds to the percentage in a given range.
*
* PercentToRange(0.34,0,100) will return 34.
* @param percent to convert to number
* @param min min range
* @param max max range
* @returns the number
*/
export function PercentToRange(percent, min, max) {
return (max - min) * percent + min;
}
/**
* Returns the highest common factor of two integers.
* @param a first parameter
* @param b second parameter
* @returns HCF of a and b
*/
export function HighestCommonFactor(a, b) {
const r = a % b;
if (r === 0) {
return b;
}
return HighestCommonFactor(b, r);
}
//# sourceMappingURL=math.scalar.functions.js.map