- 
      
- 
        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 clamp2If you run the benchmark tests sequentially the second test is always slower.
It's weird. The tests influence each other.
Nice..Thanks