Skip to content

Instantly share code, notes, and snippets.

@azz
Created September 17, 2012 13:49
Show Gist options
  • Save azz/3737355 to your computer and use it in GitHub Desktop.
Save azz/3737355 to your computer and use it in GitHub Desktop.
JS Matrix Constructors
// [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