# vec4.random() in gl-matrix

## JavaScript performance comparison

Revision 8 of this test case created

## Preparation code

``<script src="https://rawgithub.com/toji/gl-matrix/master/dist/gl-matrix-min.js"></script><script>  Benchmark.prototype.setup = function() {    var length = Math.PI;        var out = vec4.create();        var GLMAT_RANDOM = Math.random;        // original    vec4.random = function (out, scale) {        scale = scale || 1.0;            //TODO: This is a pretty awful way of doing this. Find something better.        out[0] = GLMAT_RANDOM();        out[1] = GLMAT_RANDOM();        out[2] = GLMAT_RANDOM();        out[3] = GLMAT_RANDOM();        vec4.normalize(out, out);        vec4.scale(out, out, scale);        return out;    };        // allows negative components, but is still biased    vec4.random2 = function(out, len) {        len = len || 1;        out[0] = .5 - Math.random();        out[1] = .5 - Math.random();        out[2] = .5 - Math.random();        out[3] = .5 - Math.random();        var adjust = len / vec4.length(out);        out[0] *= adjust;        out[1] *= adjust;        out[2] *= adjust;        out[3] *= adjust;        return out;    };            // return a random float in (-1, 1]    var random_float_small = function() {        return 1 - 2 * Math.random();    };        // discards some results to remove bias    vec4.random3 = function(out, len) {        len = len || 1;        var m = 0;        while (m===0||m>1) {            out[0] = random_float_small();            out[1] = random_float_small();            out[2] = random_float_small();            out[3] = random_float_small();            m = vec4.length(out);        }        var adjust = len / m;        out[0] *= adjust;        out[1] *= adjust;        out[2] *= adjust;        out[3] *= adjust;        //out[3] = Math.sqrt(len*len - vec3.squaredLength(out)); // better approximation of len        return out;    };                /**     * Random Limitless Float     *     * @returns {Number} out random float in (-Infinity, Infinity)     */    function randomLimitlessFloat() {            // random number in (-1, 1]        var r = 1 - 2 * (Math.random());            // 50% chance to get the reciprocal, which is in [1, Infinity] or (-Infinity, -1)        if (Math.random() < .5) {                // replace Infinity with -1, so the result is in (-Infinity, Infinity)            if (r===0) return -1;                return 1 / r;        }            return r;    }        vec4.random4 = function(out, len) {        len = len || 1;            var h = randomLimitlessFloat();            var h2 = h*h;        var h2p1 = h2 + 1;            var sin_h = 2*h / h2p1;        var cos_h = (1-h2) / h2p1;            var j = randomLimitlessFloat();            var j2 = j*j;        var j2p1 = j2 + 1;            var sin_j = 2*j / j2p1;        var cos_j = (1-j2) / j2p1;            var k = randomLimitlessFloat();            var k2 = k*k;        var k2p1 = k2 + 1;            var sin_k = 2*k / k2p1;        var cos_k = (1-k2) / k2p1;            out[0] = len * cos_h;        out[1] = len * sin_h * cos_j;        out[2] = len * sin_h * sin_j * cos_k;        out[3] = len * sin_h * sin_j * sin_k;            //is the bias avoided by randomizing order of the axis?        //shuffleArray(out);            return out;    };                    // return a random float in (0, PI]    var random_2PI = function() {        return Math.random() * Math.PI * 2;    };        function shuffleArray(array) {        for (var i = array.length - 1; i > 0; i--) {            var j = Math.floor(Math.random() * (i + 1));            var temp = array[i];            array[i] = array[j];            array[j] = temp;        }        return array;    }        vec4.random5 = function(out, len) {        len = len || 1;            var h = random_2PI();            var sin_h = Math.sin(h);        var cos_h = Math.cos(h);            var j = random_2PI();            var sin_j = Math.sin(j);        var cos_j = Math.cos(j);            var k = random_2PI();            var sin_k = Math.sin(k);        var cos_k = Math.cos(k);            out[0] = len * cos_h;        out[1] = len * sin_h * cos_j;        out[2] = len * sin_h * sin_j * cos_k;        out[3] = len * sin_h * sin_j * sin_k;            //shuffleArray(out);            return out;    };          };</script>``

## Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
original
``vec4.random(out, length);``
pending…
allows negative components, but still biased towards cube corners
``vec4.random2(out, length);``
pending…
rejects vectors with length > 1 to avoid bias
``vec4.random3(out, length);``
pending…
uses rational trigonometry to rotate a random amount around 3 axis
``vec4.random4(out, length);``
pending…
same idea but with classical trigonometry
``vec4.random5(out, length);``
pending…

## Revisions

You can edit these tests or add even more tests to this page by appending `/edit` to the URL. Here’s a list of current revisions for this page:

• Revision 1: published
• Revision 2: published and last updated
• Revision 3: published
• Revision 4: published
• Revision 5: published
• Revision 7: published
• Revision 8: published