Tuesday, September 1, 2015

Trig Lookup Tables

I think that was appendix J of my high school algebra book, and probably the last time I'd thought of them until I looked at this utility class in Artemis-ODB: https://github.com/junkdog/artemis-odb/blob/master/artemis/src/main/java/com/artemis/utils/TrigLUT.java

I realized I might be able to use this in Asteroids. Profiling shows that it calcs sin or cos 50-100 times per frame, and more as the level is increased. So here is my javascript port, which I just include before all the other script tags on the page:

(function () {

    var SIN_BITS = 12;
    var SIN_MASK = ~(-1 << SIN_BITS);
    var SIN_COUNT = SIN_MASK + 1;
    var radFull = (Math.PI * 2.0);
    var radToIndex = SIN_COUNT / radFull;
    var sin = new Array(SIN_COUNT);
    var cos = new Array(SIN_COUNT);

    for (var i = 0; i < SIN_COUNT; i++) {
        sin[i] = Math.sin((i + 0.5) / SIN_COUNT * radFull);
        cos[i] = Math.cos((i + 0.5) / SIN_COUNT * radFull);
    }

    Math.sin = function(rad) {
        return sin[(rad * radToIndex) & SIN_MASK];
    };

    Math.cos = function(rad) {
        return cos[(rad * radToIndex) & SIN_MASK];
    };

})();

Increasing SIN_BITS up to 16 will improve accuracy but increase memory usage. The system sin and cos functions return approximations, so how close do we need to be?

Conventional wisdom (well, stackoverflow anyway) seems to think that there is not much point, it's not really a bottleneck with modern hardware and modern browsers.

And they are correct - I can't really tell a difference in Chrone. At least not on my desktop, but it's a different story on my phone. Here it bumps the frame rate from a steady 29 fps up to 35-45 fps swings. Still not playable, but it show there is plenty of room for performance tuning, especially if I want to include mobile as a target.

No comments:

Post a Comment