1/* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 2 3Redistribution and use in source and binary forms, with or without modification, 4are permitted provided that the following conditions are met: 5 6 * Redistributions of source code must retain the above copyright notice, this 7 list of conditions and the following disclaimer. 8 * Redistributions in binary form must reproduce the above copyright notice, 9 this list of conditions and the following disclaimer in the documentation 10 and/or other materials provided with the distribution. 11 12THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 22 23/** 24 * @class 2x2 Matrix 25 * @name mat2 26 */ 27var mat2 = {}; 28 29/** 30 * Creates a new identity mat2 31 * 32 * @returns {mat2} a new 2x2 matrix 33 */ 34mat2.create = function() { 35 var out = new GLMAT_ARRAY_TYPE(4); 36 out[0] = 1; 37 out[1] = 0; 38 out[2] = 0; 39 out[3] = 1; 40 return out; 41}; 42 43/** 44 * Creates a new mat2 initialized with values from an existing matrix 45 * 46 * @param {mat2} a matrix to clone 47 * @returns {mat2} a new 2x2 matrix 48 */ 49mat2.clone = function(a) { 50 var out = new GLMAT_ARRAY_TYPE(4); 51 out[0] = a[0]; 52 out[1] = a[1]; 53 out[2] = a[2]; 54 out[3] = a[3]; 55 return out; 56}; 57 58/** 59 * Copy the values from one mat2 to another 60 * 61 * @param {mat2} out the receiving matrix 62 * @param {mat2} a the source matrix 63 * @returns {mat2} out 64 */ 65mat2.copy = function(out, a) { 66 out[0] = a[0]; 67 out[1] = a[1]; 68 out[2] = a[2]; 69 out[3] = a[3]; 70 return out; 71}; 72 73/** 74 * Set a mat2 to the identity matrix 75 * 76 * @param {mat2} out the receiving matrix 77 * @returns {mat2} out 78 */ 79mat2.identity = function(out) { 80 out[0] = 1; 81 out[1] = 0; 82 out[2] = 0; 83 out[3] = 1; 84 return out; 85}; 86 87/** 88 * Transpose the values of a mat2 89 * 90 * @param {mat2} out the receiving matrix 91 * @param {mat2} a the source matrix 92 * @returns {mat2} out 93 */ 94mat2.transpose = function(out, a) { 95 // If we are transposing ourselves we can skip a few steps but have to cache some values 96 if (out === a) { 97 var a1 = a[1]; 98 out[1] = a[2]; 99 out[2] = a1; 100 } else { 101 out[0] = a[0]; 102 out[1] = a[2]; 103 out[2] = a[1]; 104 out[3] = a[3]; 105 } 106 107 return out; 108}; 109 110/** 111 * Inverts a mat2 112 * 113 * @param {mat2} out the receiving matrix 114 * @param {mat2} a the source matrix 115 * @returns {mat2} out 116 */ 117mat2.invert = function(out, a) { 118 var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], 119 120 // Calculate the determinant 121 det = a0 * a3 - a2 * a1; 122 123 if (!det) { 124 return null; 125 } 126 det = 1.0 / det; 127 128 out[0] = a3 * det; 129 out[1] = -a1 * det; 130 out[2] = -a2 * det; 131 out[3] = a0 * det; 132 133 return out; 134}; 135 136/** 137 * Calculates the adjugate of a mat2 138 * 139 * @param {mat2} out the receiving matrix 140 * @param {mat2} a the source matrix 141 * @returns {mat2} out 142 */ 143mat2.adjoint = function(out, a) { 144 // Caching this value is nessecary if out == a 145 var a0 = a[0]; 146 out[0] = a[3]; 147 out[1] = -a[1]; 148 out[2] = -a[2]; 149 out[3] = a0; 150 151 return out; 152}; 153 154/** 155 * Calculates the determinant of a mat2 156 * 157 * @param {mat2} a the source matrix 158 * @returns {Number} determinant of a 159 */ 160mat2.determinant = function (a) { 161 return a[0] * a[3] - a[2] * a[1]; 162}; 163 164/** 165 * Multiplies two mat2's 166 * 167 * @param {mat2} out the receiving matrix 168 * @param {mat2} a the first operand 169 * @param {mat2} b the second operand 170 * @returns {mat2} out 171 */ 172mat2.multiply = function (out, a, b) { 173 var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; 174 var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; 175 out[0] = a0 * b0 + a1 * b2; 176 out[1] = a0 * b1 + a1 * b3; 177 out[2] = a2 * b0 + a3 * b2; 178 out[3] = a2 * b1 + a3 * b3; 179 return out; 180}; 181 182/** 183 * Alias for {@link mat2.multiply} 184 * @function 185 */ 186mat2.mul = mat2.multiply; 187 188/** 189 * Rotates a mat2 by the given angle 190 * 191 * @param {mat2} out the receiving matrix 192 * @param {mat2} a the matrix to rotate 193 * @param {Number} rad the angle to rotate the matrix by 194 * @returns {mat2} out 195 */ 196mat2.rotate = function (out, a, rad) { 197 var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], 198 s = Math.sin(rad), 199 c = Math.cos(rad); 200 out[0] = a0 * c + a1 * s; 201 out[1] = a0 * -s + a1 * c; 202 out[2] = a2 * c + a3 * s; 203 out[3] = a2 * -s + a3 * c; 204 return out; 205}; 206 207/** 208 * Scales the mat2 by the dimensions in the given vec2 209 * 210 * @param {mat2} out the receiving matrix 211 * @param {mat2} a the matrix to rotate 212 * @param {vec2} v the vec2 to scale the matrix by 213 * @returns {mat2} out 214 **/ 215mat2.scale = function(out, a, v) { 216 var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], 217 v0 = v[0], v1 = v[1]; 218 out[0] = a0 * v0; 219 out[1] = a1 * v1; 220 out[2] = a2 * v0; 221 out[3] = a3 * v1; 222 return out; 223}; 224 225/** 226 * Returns a string representation of a mat2 227 * 228 * @param {mat2} mat matrix to represent as a string 229 * @returns {String} string representation of the matrix 230 */ 231mat2.str = function (a) { 232 return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; 233}; 234 235if(typeof(exports) !== 'undefined') { 236 exports.mat2 = mat2; 237} 238