-
-
Save demonixis/4202528 to your computer and use it in GitHub Desktop.
var MathHelper = { | |
// Get a value between two values | |
clamp: function (value, min, max) { | |
if (value < min) { | |
return min; | |
} | |
else if (value > max) { | |
return max; | |
} | |
return value; | |
}, | |
// Get the linear interpolation between two value | |
lerp: function (value1, value2, amount) { | |
amount = amount < 0 ? 0 : amount; | |
amount = amount > 1 ? 1 : amount; | |
return value1 + (value2 - value1) * amount; | |
} | |
}; |
Math.lerp function has two issues… First: the "amount" can be less than zero or greater than one; this allows for extrapolation (see: wikipedia); so no reason to pin between these values. Second: the value1 + (value2 - value1) * amount;
equation is Imprecise, it does not guarantee v = v1
when t = 1
, due to floating-point arithmetic error. (see wikipedia)
Use return (1 - amount) * value1 + amount * value2;
instead;
Also, clamp can be made faster by using Math.min & Math.max instead of the conditional comparison expressions; use:
return Math.min(Math.max(value, min), max);
instead.
Another useful math routine is wrap:
Math.wrap = function(inValue, inMin, inMax) {
valueRange = inMax - inMin;
return (inMin + ((((inValue - inMin) % valueRange) + valueRange) % valueRange));
}
Use it like this:
angle = Math.wrap(angle, 0, 360); // wrap between 0 & 360°
angle = Math.wrap(angle, -90, +90); // wrap between +/-90°
@geowar1 Did you benchmark the Math.min(Math.max())
being faster? I'd be surprised if that was true.
The "if" method of clamp is ca. 4,5 times faster than the math min/max method.
Tested with chrome version 60.0.3112.90 64bit.
Benchmark:
Run the clamp function x-times (e.g. 1 000 000 000) with limits min 25% of range (x-times) and max 75%.
function runBench(func) {
console.log("Benchmark '" + func.name +"' running ...");
let value = 0;
let now = new Date().getTime();
let range = 1000000000;
let rangeMin = range * 0.25;
let rangeMax = range * 0.75;
for (let i = 0; i < range; i++) {
value = func(i, rangeMin, rangeMax);
}
console.log("Time: " + (new Date().getTime() - now) + " ms");
}
runBench(clamp1); // alternate with clamp2
If you run the benchmark tests sequentially the second test is always slower.
It's weird. The tests influence each other.
Nice..Thanks