Fast Maths library
This is a library for faster trigonometric functions in JavaScript by way of LUTs.
It optimizes Math.sin
, Math.cos
, and Math.atan
with configurable resolution. Demo here.
JSPerf shows a speed increase of 400% in Chrome. Not bad!
Usage
var fMath = new FMath();
fMath.cos(Math.PI);
fMath.sin(Math.PI);
fMath.atan(Math.PI/6);
new FMath(params)
Creates a new object that you can use in place of the built-in Math
for methods like sin
and cos
. Default params
:
params = {
resolution: 360,
minAtan: -40,
maxAtan: 40
nbCos: 360,
nbSin: 360,
nbAtan: 360
};
FMath#cos
≈ Math.cos
FMath#sin
≈ Math.sin
FMath#atan
≈ Math.atan
atan is a particular case, as its range is (-∞, ∞)
. Since we cannot cache an infinite number of values, you can pass minAtan
(default -40
) and maxAtan
(default 40
) to the constructor. ±40 was chosen since atan(1.54) ≈ 40 and the range of atan
is (-π/2, π/2)
≈ (-1.57, 1.57)
. This is near the limit of the function, and still avoids having to cache too many numbers.
If you input a value lower/higher than minAtan
/maxAtan
, the function will return -Math.PI / 2
or Math.PI / 2
.
If you use atan
, be careful that due to the nature of this function, values near 0 jump very fast from negative to positive. If you don't have a big enough resolution, your results near 0 will be very imprecise. Try to keep the minAtan - maxAtan interval as low as possible, and the resolution high for atan.
Here is how the tan
function looks. As you can see, its limit tend to -∞ and +∞:
And here is how the atan
function looks:
FMath#tan/csc/sec/etc
If you want to add others, don't hesitate to file a pull request!
Design choices
In theory, we could only store a cosine array, or even a quarter of cosine array and find the rest at runtime. But the point of this library is to optimize as much as possible the execution time of the sine/cosine functions. Additional logic in the functions would mean slower execution time, which is not the intent here.
On the other hand, memory is cheap and storing a few floats is really not a problem. For a table of 360 values you store 720 32bit float, which is negligible.
This library avoids memoization.
It is true that it would be possible to just cache values on the go and then retrieve them, but that too would need additional logic at runtime,
and would make the processing time of the functions inconsistent (first time you get a number is slower than the rest of the time).