166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
366a37686207944273ced825e0e8b6b6375f8c3deJamie GennisRedistribution and use in source and binary forms, with or without modification,
466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisare permitted provided that the following conditions are met:
566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  * Redistributions of source code must retain the above copyright notice, this
766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    list of conditions and the following disclaimer.
866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  * Redistributions in binary form must reproduce the above copyright notice,
966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    this list of conditions and the following disclaimer in the documentation
1066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    and/or other materials provided with the distribution.
1166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
1266a37686207944273ced825e0e8b6b6375f8c3deJamie GennisTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1366a37686207944273ced825e0e8b6b6375f8c3deJamie GennisANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1466a37686207944273ced825e0e8b6b6375f8c3deJamie GennisWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1566a37686207944273ced825e0e8b6b6375f8c3deJamie GennisDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
1666a37686207944273ced825e0e8b6b6375f8c3deJamie GennisANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1866a37686207944273ced825e0e8b6b6375f8c3deJamie GennisLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1966a37686207944273ced825e0e8b6b6375f8c3deJamie GennisANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2166a37686207944273ced825e0e8b6b6375f8c3deJamie GennisSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
2266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
2366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
2466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @class 2x2 Matrix
2566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @name mat2
2666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
2766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisvar mat2 = {};
2866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
2966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
3066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Creates a new identity mat2
3166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
3266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {mat2} a new 2x2 matrix
3366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
3466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.create = function() {
3566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    var out = new GLMAT_ARRAY_TYPE(4);
3666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[0] = 1;
3766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[1] = 0;
3866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[2] = 0;
3966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[3] = 1;
4066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return out;
4166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
4266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
4366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
4466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Creates a new mat2 initialized with values from an existing matrix
4566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
4666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} a matrix to clone
4766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {mat2} a new 2x2 matrix
4866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
4966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.clone = function(a) {
5066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    var out = new GLMAT_ARRAY_TYPE(4);
5166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[0] = a[0];
5266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[1] = a[1];
5366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[2] = a[2];
5466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[3] = a[3];
5566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return out;
5666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
5766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
5866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
5966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Copy the values from one mat2 to another
6066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
6166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} out the receiving matrix
6266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} a the source matrix
6366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {mat2} out
6466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
6566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.copy = function(out, a) {
6666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[0] = a[0];
6766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[1] = a[1];
6866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[2] = a[2];
6966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[3] = a[3];
7066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return out;
7166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
7266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
7366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
7466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Set a mat2 to the identity matrix
7566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
7666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} out the receiving matrix
7766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {mat2} out
7866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
7966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.identity = function(out) {
8066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[0] = 1;
8166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[1] = 0;
8266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[2] = 0;
8366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[3] = 1;
8466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return out;
8566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
8666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
8766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
8866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Transpose the values of a mat2
8966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
9066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} out the receiving matrix
9166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} a the source matrix
9266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {mat2} out
9366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
9466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.transpose = function(out, a) {
9566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    // If we are transposing ourselves we can skip a few steps but have to cache some values
9666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    if (out === a) {
9766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var a1 = a[1];
9866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        out[1] = a[2];
9966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        out[2] = a1;
10066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    } else {
10166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        out[0] = a[0];
10266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        out[1] = a[2];
10366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        out[2] = a[1];
10466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        out[3] = a[3];
10566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    }
10666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
10766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return out;
10866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
10966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
11066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
11166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Inverts a mat2
11266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
11366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} out the receiving matrix
11466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} a the source matrix
11566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {mat2} out
11666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
11766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.invert = function(out, a) {
11866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
11966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
12066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        // Calculate the determinant
12166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        det = a0 * a3 - a2 * a1;
12266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
12366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    if (!det) {
12466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        return null;
12566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    }
12666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    det = 1.0 / det;
12766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
12866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[0] =  a3 * det;
12966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[1] = -a1 * det;
13066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[2] = -a2 * det;
13166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[3] =  a0 * det;
13266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
13366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return out;
13466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
13566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
13666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
13766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Calculates the adjugate of a mat2
13866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
13966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} out the receiving matrix
14066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} a the source matrix
14166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {mat2} out
14266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
14366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.adjoint = function(out, a) {
14466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    // Caching this value is nessecary if out == a
14566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    var a0 = a[0];
14666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[0] =  a[3];
14766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[1] = -a[1];
14866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[2] = -a[2];
14966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[3] =  a0;
15066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
15166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return out;
15266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
15366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
15466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
15566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Calculates the determinant of a mat2
15666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
15766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} a the source matrix
15866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {Number} determinant of a
15966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
16066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.determinant = function (a) {
16166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return a[0] * a[3] - a[2] * a[1];
16266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
16366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
16466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
16566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Multiplies two mat2's
16666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
16766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} out the receiving matrix
16866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} a the first operand
16966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} b the second operand
17066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {mat2} out
17166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
17266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.multiply = function (out, a, b) {
17366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
17466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
17566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[0] = a0 * b0 + a1 * b2;
17666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[1] = a0 * b1 + a1 * b3;
17766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[2] = a2 * b0 + a3 * b2;
17866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[3] = a2 * b1 + a3 * b3;
17966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return out;
18066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
18166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
18266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
18366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Alias for {@link mat2.multiply}
18466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @function
18566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
18666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.mul = mat2.multiply;
18766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
18866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
18966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Rotates a mat2 by the given angle
19066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
19166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} out the receiving matrix
19266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} a the matrix to rotate
19366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {Number} rad the angle to rotate the matrix by
19466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {mat2} out
19566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
19666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.rotate = function (out, a, rad) {
19766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
19866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        s = Math.sin(rad),
19966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        c = Math.cos(rad);
20066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[0] = a0 *  c + a1 * s;
20166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[1] = a0 * -s + a1 * c;
20266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[2] = a2 *  c + a3 * s;
20366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[3] = a2 * -s + a3 * c;
20466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return out;
20566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
20666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
20766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
20866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Scales the mat2 by the dimensions in the given vec2
20966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
21066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} out the receiving matrix
21166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} a the matrix to rotate
21266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {vec2} v the vec2 to scale the matrix by
21366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {mat2} out
21466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis **/
21566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.scale = function(out, a, v) {
21666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
21766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        v0 = v[0], v1 = v[1];
21866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[0] = a0 * v0;
21966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[1] = a1 * v1;
22066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[2] = a2 * v0;
22166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    out[3] = a3 * v1;
22266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return out;
22366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
22466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
22566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
22666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * Returns a string representation of a mat2
22766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis *
22866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @param {mat2} mat matrix to represent as a string
22966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @returns {String} string representation of the matrix
23066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
23166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennismat2.str = function (a) {
23266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
23366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis};
23466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
23566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisif(typeof(exports) !== 'undefined') {
23666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    exports.mat2 = mat2;
23766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis}
238