8ab6afc0ff1f6b225e52d7489864024d814b37fcTrippvar MatrixUtil = {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Used as value for the _rounding method.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @property _rounder
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @private
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp _rounder: 100000,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Rounds values
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method _round
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @private
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp _round: function(val) {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp val = Math.round(val * MatrixUtil._rounder) / MatrixUtil._rounder;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return val;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Converts a radian value to a degree.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method rad2deg
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Number} rad Radian value to be converted.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Number
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp rad2deg: function(rad) {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var deg = rad * (180 / Math.PI);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return deg;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Converts a degree value to a radian.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method deg2rad
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Number} deg Degree value to be converted to radian.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Number
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp deg2rad: function(deg) {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var rad = deg * (Math.PI / 180);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return rad;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Converts an angle to a radian
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method angle2rad
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Objecxt} val Value to be converted to radian.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Number
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp angle2rad: function(val) {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if (typeof val === 'string' && val.indexOf('rad') > -1) {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp val = parseFloat(val);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp } else { // default to deg
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp val = MatrixUtil.deg2rad(parseFloat(val));
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return val;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Converts a transform object to an array of column vectors.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * / \
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * | matrix[0][0] matrix[1][0] matrix[2][0] |
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * | matrix[0][1] matrix[1][1] matrix[2][1] |
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * | matrix[0][2] matrix[1][2] matrix[2][2] |
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * \ /
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method getnxn
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Array
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp convertTransformToArray: function(matrix)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var matrixArray = [
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp [matrix.a, matrix.c, matrix.dx],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp [matrix.b, matrix.d, matrix.dy],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp [0, 0, 1]
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp ];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return matrixArray;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Returns the determinant of a given matrix.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * / \
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * | matrix[0][0] matrix[1][0] matrix[2][0] |
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * | matrix[0][1] matrix[1][1] matrix[2][1] |
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * | matrix[0][2] matrix[1][2] matrix[2][2] |
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * | matrix[0][3] matrix[1][3] matrix[2][3] |
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * \ /
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method getDeterminant
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Array} matrix An nxn matrix represented an array of vector (column) arrays. Each vector array has index for each row.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Number
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp getDeterminant: function(matrix)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var determinant = 0,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp len = matrix.length,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp i = 0,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp multiplier;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if(len == 2)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(; i < len; ++i)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp multiplier = matrix[i][0];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if(i % 2 === 0 || i === 0)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp determinant += multiplier * MatrixUtil.getDeterminant(MatrixUtil.getMinors(matrix, i, 0));
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp else
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp determinant -= multiplier * MatrixUtil.getDeterminant(MatrixUtil.getMinors(matrix, i, 0));
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return determinant;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Returns the inverse of a matrix
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method inverse
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param Array matrix An array representing an nxn matrix
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Array
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * / \
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * | matrix[0][0] matrix[1][0] matrix[2][0] |
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * | matrix[0][1] matrix[1][1] matrix[2][1] |
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * | matrix[0][2] matrix[1][2] matrix[2][2] |
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * | matrix[0][3] matrix[1][3] matrix[2][3] |
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * \ /
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp inverse: function(matrix)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var determinant = 0,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp len = matrix.length,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp i = 0,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp j,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp inverse,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp adjunct = [],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp //vector representing 2x2 matrix
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp minor = [],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp multiplier;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if(len === 2)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp determinant = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp inverse = [
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp [matrix[1][1] * determinant, -matrix[1][0] * determinant],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp [-matrix[0][1] * determinant, matrix[0][0] * determinant]
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp ];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp else
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp determinant = MatrixUtil.getDeterminant(matrix);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(; i < len; ++i)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp adjunct[i] = [];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(j = 0; j < len; ++j)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp minor = MatrixUtil.getMinors(matrix, j, i);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp adjunct[i][j] = MatrixUtil.getDeterminant(minor);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if((i + j) % 2 !== 0 && (i + j) !== 0)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp adjunct[i][j] *= -1;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp inverse = MatrixUtil.scalarMultiply(adjunct, 1/determinant);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return inverse;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Multiplies a matrix by a numeric value.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method scalarMultiply
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Array} matrix The matrix to be altered.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Number} multiplier The number to multiply against the matrix.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Array
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp scalarMultiply: function(matrix, multiplier)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var i = 0,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp j,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp len = matrix.length;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(; i < len; ++i)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(j = 0; j < len; ++j)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp matrix[i][j] = MatrixUtil._round(matrix[i][j] * multiplier);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return matrix;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Returns the transpose for an nxn matrix.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method transpose
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param matrix An nxn matrix represented by an array of vector arrays.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Array
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp transpose: function(matrix)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var len = matrix.length,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp i = 0,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp j = 0,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp transpose = [];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(; i < len; ++i)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp transpose[i] = [];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(j = 0; j < len; ++j)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp transpose[i].push(matrix[j][i]);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return transpose;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Returns a matrix of minors based on a matrix, column index and row index.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method getMinors
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Array} matrix The matrix from which to extract the matrix of minors.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Number} columnIndex A zero-based index representing the specified column to exclude.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Number} rowIndex A zero-based index represeenting the specified row to exclude.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Array
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp getMinors: function(matrix, columnIndex, rowIndex)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var minors = [],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp len = matrix.length,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp i = 0,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp j,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp column;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(; i < len; ++i)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if(i !== columnIndex)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp column = [];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(j = 0; j < len; ++j)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if(j !== rowIndex)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp column.push(matrix[i][j]);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp minors.push(column);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return minors;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Returns the sign of value
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method sign
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Number} val value to be interpreted
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Number
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp sign: function(val)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return val === 0 ? 1 : val/Math.abs(val);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Multiplies a vector and a matrix
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method vectorMatrixProduct
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Array} vector Array representing a column vector
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Array} matrix Array representing an nxn matrix
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Array
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp vectorMatrixProduct: function(vector, matrix)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var i,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp j,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp len = vector.length,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp product = [],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp rowProduct;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(i = 0; i < len; ++i)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp rowProduct = 0;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(j = 0; j < len; ++j)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp rowProduct += vector[i] * matrix[i][j];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp product[i] = rowProduct;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return product;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Breaks up a 2d transform matrix into a series of transform operations.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method decompose
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Array} 3x3 matrix array
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Array
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp decompose: function(matrix)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var a = matrix[0][0],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp b = matrix[1][0],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp c = matrix[0][1],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp d = matrix[1][1],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp dx = matrix[0][2],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp dy = matrix[1][2],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp translate = [dx, dy],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp rotate,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp sx,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp sy,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp sign = sign,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp shear;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if((a * d - b * c) === 0)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return false;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp //get length of vector(ab)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp sx = MatrixUtil._round(Math.sqrt(a * a + b * b));
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp //normalize components of vector(ab)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp a /= sx;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp b /= sx;
83e1c423e969705408dfcf7d94c7cd3c762e18f8Tripp shear = MatrixUtil._round(a * c + b * d);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp c -= a * shear;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp d -= b * shear;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp //get length of vector(cd)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp sy = MatrixUtil._round(Math.sqrt(c * c + d * d));
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp //normalize components of vector(cd)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp c /= sy;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp d /= sy;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp shear /=sy;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if(a * b < c * d)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp a = -a;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp b = -b;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp c = -c;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp d = -d;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp shear = -shear;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp sx = -sx;
83e1c423e969705408dfcf7d94c7cd3c762e18f8Tripp sy = -sy;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
83e1c423e969705408dfcf7d94c7cd3c762e18f8Tripp shear = MatrixUtil._round(MatrixUtil.rad2deg(Math.atan(shear)));
83e1c423e969705408dfcf7d94c7cd3c762e18f8Tripp rotate = MatrixUtil._round(MatrixUtil.rad2deg(Math.atan2(matrix[1][0], matrix[0][0])));
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return [
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp ["translate", dx, dy],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp ["rotate", rotate],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp ["skewX", shear],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp ["scale", sx, sy]
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp ];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Parses a transform string and returns an array of transform arrays.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method getTransformArray
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {String} val A transform string
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Array
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp getTransformArray: function(transform) {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var re = /\s*([a-z]*)\(([\w,\.,\-,\s]*)\)/gi,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp transforms = [],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp args,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp m,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp decomp,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp methods = MatrixUtil.transformMethods;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp while ((m = re.exec(transform))) {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if (methods.hasOwnProperty(m[1]))
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp args = m[2].split(',');
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp args.unshift(m[1]);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp transforms.push(args);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp else if(m[1] == "matrix")
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp args = m[2].split(',');
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp decomp = MatrixUtil.decompose([
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp [args[0], args[2], args[4]],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp [args[1], args[3], args[5]],
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp [0, 0, 1]
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp ]);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp transforms.push(decomp[0]);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp transforms.push(decomp[1]);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp transforms.push(decomp[2]);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp transforms.push(decomp[3]);
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return transforms;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Returns an array of transform arrays representing transform functions and arguments.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method getTransformFunctionArray
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Array
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp getTransformFunctionArray: function(transform) {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var list;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp switch(transform)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp case "skew" :
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp list = [transform, 0, 0];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp break;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp case "scale" :
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp list = [transform, 1, 1];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp break;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp case "scaleX" :
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp list = [transform, 1];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp break;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp case "scaleY" :
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp list = [transform, 1];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp break;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp case "translate" :
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp list = [transform, 0, 0];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp break;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp default :
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp list = [transform, 0];
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp break;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return list;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Compares to arrays or transform functions to ensure both contain the same functions in the same
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * order.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @method compareTransformSequence
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Array} list1 Array to compare
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @param {Array} list2 Array to compare
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @return Boolean
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp compareTransformSequence: function(list1, list2)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp var i = 0,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp len = list1.length,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp len2 = list2.length,
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp isEqual = len === len2;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if(isEqual)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp for(; i < len; ++i)
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp if(list1[i][0] != list2[i][0])
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp isEqual = false;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp break;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp return isEqual;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp },
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp /**
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * Mapping of possible transform method names.
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp *
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @property transformMethods
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp * @type Object
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp */
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp transformMethods: {
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp rotate: "rotate",
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp skew: "skew",
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp skewX: "skewX",
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp skewY: "skewY",
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp translate: "translate",
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp translateX: "translateX",
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp translateY: "tranlsateY",
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp scale: "scale",
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp scaleX: "scaleX",
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp scaleY: "scaleY"
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp }
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp};
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp
8ab6afc0ff1f6b225e52d7489864024d814b37fcTrippY.MatrixUtil = MatrixUtil;
8ab6afc0ff1f6b225e52d7489864024d814b37fcTripp