Created
September 17, 2012 13:49
-
-
Save azz/3737355 to your computer and use it in GitHub Desktop.
JS Matrix Constructors
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// [Not sure how to implement multiple constructors for the same object using a psuedo-static method | |
// (hence return this)... FIXME if incorrect. | |
/** | |
* Construct a 2 dimensional rotation matrix about the point (0,0) | |
* @param {Number} theta the angle to rotate | |
*/ | |
function Matrix.create2DRotation(theta) { | |
this.columnns = this.rows = 2; | |
var sinTheta = Math.sin(theta); | |
var cosTheta = Math.cos(theta); | |
// [DF] may need to switch elements at index 1 and 2, depending on your v * M implemntation. (vector column/row) | |
// Assumed: [x,y,z] * M | |
// Same applies for all following matrices. Just take the transpose if you've done it the other way. | |
this.elements = [cosTheta, -sinTheta, sinTheta, cosTheta]; | |
return this; | |
} | |
/** | |
* Construct a 3 dimensional rotation matrix about the X axis | |
* @param {Number} theta the angle to rotate about the X axis | |
*/ | |
function Matrix.createRotationX(theta) { | |
this.columns = this.rows = 3; | |
var sinTheta = Math.sin(theta); | |
var cosTheta = Math.cos(theta); | |
this.elements = [ | |
1, 0, 0, | |
0, cosTheta, sinTheta, | |
0, -sinTheta, cosTheta | |
]; | |
return this; | |
} | |
/** | |
* Construct a 3 dimensional rotation matrix about the Y axis | |
* @param {Number} theta the angle to rotate about the Y axis | |
*/ | |
function Matrix.createRotationY(theta) { | |
this.columns = this.rows = 3; | |
var sinTheta = Math.sin(theta); | |
var cosTheta = Math.cos(theta); | |
this.elements = [ | |
cosTheta, 0, -sinTheta, | |
0, 0, 1, | |
sinTheta, 0, cosTheta | |
]; | |
return this; | |
} | |
/** | |
* Construct a 3 dimensional rotation matrix about the Z axis | |
* @param {Number} theta the angle to rotate about the Z axis | |
*/ | |
function Matrix.createRotationZ(theta) { | |
this.columns = this.rows = 3; | |
var sinTheta = Math.sin(theta); | |
var cosTheta = Math.cos(theta); | |
this.elements = [ | |
cosTheta, sinTheta, 0, | |
-sinTheta, cosTheta, 1, | |
0, 0, 1 | |
]; | |
return this; | |
} | |
/** | |
* Construct a 3 dimensional rotation matrix about an arbitrary axis | |
* @param {Number} theta the angle to rotate about the axis | |
* @param {Vector} axis the Vector representing the axis | |
*/ | |
function Matrix.createRotationFromAxis(theta, axis) { | |
this.columns = this.rows = 3; | |
var sinT = Math.sin(theta); | |
var cosT = Math.cos(theta); | |
var cTI = 1 - cosT; | |
var n = axis.normalize(): | |
var nx = n.components[0] || throw "Illegal Vector"; | |
var ny = n.components[1] || throw "Illegal Vector"; | |
var nz = n.components[2] || throw "Illegal Vector"; | |
this.elements = [ // ermagherd, arbitrary arity! | |
nx * nx * cTI + cosT, nx * ny * cTI + nz * sinT, nx * nz * cTI - ny * sinT, | |
nx * ny * cTI + nz * sinT, ny * ny * cTI + cosT, ny * nz * cTI + nx * sinT, | |
nx * nz * cTI + ny * sinT, ny * nz * cTI - nx * sinT, nz * nz * cTI + cosT | |
]; | |
return this; | |
} | |
/** | |
* Construct a 3D scaling matrix | |
* @param {Vector} the vector to scale by | |
* @param {Number} the scalar quantity | |
*/ | |
function Matrix.createScale(vector, k) { | |
this.rows = this.columns = 3; | |
if (vector.components.length != 3) | |
throw "Illegal Vector"; | |
var n = vector.normalize(); | |
var nx = n.components[0] || throw "Illegal Vector"; | |
var ny = n.components[1] || throw "Illegal Vector"; | |
var nz = n.components[2] || throw "Illegal Vector"; | |
var km1 = k - 1; | |
this.elements = [ | |
1 + km1 * nx * nx, km1 * nx * nz, km1 * nx * nz, | |
km1 * nx * ny, 1 + km1 * ny * ny, km1 * ny * nz, | |
km1 * nx * nz, km1 * ny * nz, 1 + km1 * nz * nz | |
]; | |
return this; | |
} | |
/** | |
* Construct a 2D scaling matrix | |
* @param {Vector} the vector to scale by | |
* @param {Number} the scalar quantity | |
*/ | |
function Matrix.createScale(vector, k) { | |
if (vector.components.length != 2) | |
throw "Illegal Vector"; | |
this.rows = this.columns = 3; | |
var n = vector.normalize(); | |
var nx = n.components[0] || throw "Illegal Vector"; | |
var ny = n.components[1] || throw "Illegal Vector"; | |
var km1 = k - 1; | |
this.elements = [ | |
1 + km1 * nx * nx, km1 * nx * ny, | |
km1 * nx * ny, 1 + km1 * ny * ny | |
]; | |
return this; | |
} | |
/** | |
* Construct a rotation to peform a 3D affine translation | |
* | |
* // Example Usage: | |
* var rotation = new Matrix.createRotationY(Math.PI/4); | |
* var translation = new Matrix.createTranlation(5, 0, 0); | |
* // rotate foo 45deg then tranlate 5 units in it's object x-direction | |
* foo.position = rotation.multiply(translation); | |
* | |
* @param {Number} dx x displacement | |
* @param {Number} dy y displacement | |
* @param {Number} dz z displacement | |
*/ | |
function Matrix.createTranlation(dx, dy, dz) { | |
this.columns = this.rows = 4; | |
this.elements = [ | |
1, 0, 0, 0, | |
0, 1, 0, 0, | |
0, 0, 1, 0, | |
dx, dy, dz, 1 | |
]; | |
return this; | |
} | |
/** | |
* Construct a rotation to peform a 2D affine translation | |
* @param {Number} dx x displacement | |
* @param {Number} dy y displacement | |
*/ | |
function Matrix.createTranslation(dx, dy) { | |
this.columns = this.rows = 3; | |
this.elements = [ | |
1, 0, 0, | |
0, 1, 0, | |
dx, dy, 1 | |
]; | |
return this; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment