blob: 2208b13e7c2c96818ec4d6d1ba4e896fe2b0bb64 [file] [log] [blame]
Jamie Gennis66a37682013-07-15 18:29:18 -07001/* 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}