248 lines
6.7 KiB
JavaScript
248 lines
6.7 KiB
JavaScript
goog.provide('ol.matrix');
|
|
|
|
/**
|
|
* Collection of matrix transformation functions. The element order is
|
|
* compatible with the [SVGMatrix interface](https://developer.mozilla.org/en-US/docs/Web/API/SVGMatrix):
|
|
* ```
|
|
* [ a c e ]
|
|
* [ b d f ]
|
|
* [ 0 0 1 ]
|
|
* ```
|
|
*/
|
|
|
|
|
|
/**
|
|
* Create an identity matrix.
|
|
* @return {!ol.Matrix} Identity matrix.
|
|
*/
|
|
ol.matrix.create = function() {
|
|
return [1, 0, 0, 1, 0, 0];
|
|
};
|
|
|
|
|
|
/**
|
|
* Check if two matrices are equal.
|
|
* @param {!ol.Matrix} mat1 Matrix 1.
|
|
* @param {!ol.Matrix} mat2 Matrix 2.
|
|
* @return {boolean} Matrix 1 and Matrix 2 are equal.
|
|
*/
|
|
ol.matrix.equals = function(mat1, mat2) {
|
|
return mat1[0] == mat2[0] &&
|
|
mat1[1] == mat2[1] &&
|
|
mat1[2] == mat2[2] &&
|
|
mat1[3] == mat2[3] &&
|
|
mat1[4] == mat2[4] &&
|
|
mat1[5] == mat2[5];
|
|
};
|
|
|
|
|
|
/**
|
|
* Resets the given matrix to an identity matrix.
|
|
* @param {!ol.Matrix} mat Matrix.
|
|
* @return {!ol.Matrix} Matrix.
|
|
*/
|
|
ol.matrix.makeIdentity = function(mat) {
|
|
return ol.matrix.setTransform(mat, 1, 0, 0, 1, 0, 0);
|
|
};
|
|
|
|
|
|
/**
|
|
* Multiply two matrices with each other.
|
|
* @param {!ol.Matrix} mat1 Matrix 1.
|
|
* @param {!ol.Matrix} mat2 Matrix 2.
|
|
* @param {ol.Matrix=} opt_mat Optional matrix for the result.
|
|
* @return {!ol.Matrix} Result matrix.
|
|
*/
|
|
ol.matrix.multiply = function(mat1, mat2, opt_mat) {
|
|
var mat = opt_mat ? opt_mat : ol.matrix.create();
|
|
ol.matrix.setTransform(mat, mat1[0], mat1[1], mat1[2], mat1[3], mat1[4], mat1[5]);
|
|
return ol.matrix.transform(mat, mat2[0], mat2[1], mat2[2], mat2[3], mat2[4], mat2[5]);
|
|
};
|
|
|
|
/**
|
|
* Set the transform for a given matrix.
|
|
* @param {!ol.Matrix} mat Matrix.
|
|
* @param {number} a The a component of the matrix.
|
|
* @param {number} b The b component of the matrix.
|
|
* @param {number} c The c component of the matrix.
|
|
* @param {number} d The d component of the matrix.
|
|
* @param {number} e The e component of the matrix.
|
|
* @param {number} f The f component of the matrix.
|
|
* @return {!ol.Matrix} Matrix with transform applied.
|
|
*/
|
|
ol.matrix.setTransform = function(mat, a, b, c, d, e, f) {
|
|
mat[0] = a;
|
|
mat[1] = b;
|
|
mat[2] = c;
|
|
mat[3] = d;
|
|
mat[4] = e;
|
|
mat[5] = f;
|
|
return mat;
|
|
};
|
|
|
|
|
|
/**
|
|
* Set transform on one matrix from another matrix.
|
|
* @param {!ol.Matrix} mat1 Matrix to set transform to.
|
|
* @param {!ol.Matrix} mat2 Matrix to set transform from.
|
|
* @return {!ol.Matrix} mat1 with transform from mat2 applied.
|
|
*/
|
|
ol.matrix.setFromArray = function(mat1, mat2) {
|
|
mat1[0] = mat2[0];
|
|
mat1[1] = mat2[1];
|
|
mat1[2] = mat2[2];
|
|
mat1[3] = mat2[3];
|
|
mat1[4] = mat2[4];
|
|
mat1[5] = mat2[5];
|
|
return mat1;
|
|
};
|
|
|
|
|
|
/**
|
|
* Rotates the given matrix.
|
|
* @param {!ol.Matrix} mat Matrix.
|
|
* @param {number} rotation Angle in radians.
|
|
* @return {!ol.Matrix} Rotated matrix.
|
|
*/
|
|
ol.matrix.rotate = function(mat, rotation) {
|
|
var cos = Math.cos(rotation);
|
|
var sin = Math.sin(rotation);
|
|
return ol.matrix.transform(mat, cos, sin, -sin, cos, 0, 0);
|
|
};
|
|
|
|
|
|
/**
|
|
* Multiplies the given matrix with new matrix values.
|
|
* @see {@link ol.Matrix#multiply}.
|
|
*
|
|
* @param {!ol.Matrix} mat Matrix.
|
|
* @param {number} a The a component of the matrix.
|
|
* @param {number} b The b component of the matrix.
|
|
* @param {number} c The c component of the matrix.
|
|
* @param {number} d The d component of the matrix.
|
|
* @param {number} e The e component of the matrix.
|
|
* @param {number} f The f component of the matrix.
|
|
* @return {!ol.Matrix} Transformed matrix.
|
|
*/
|
|
ol.matrix.transform = function(mat, a, b, c, d, e, f) {
|
|
var matA = mat[0];
|
|
var matB = mat[1];
|
|
var matC = mat[2];
|
|
var matD = mat[3];
|
|
var matE = mat[4];
|
|
var matF = mat[5];
|
|
|
|
mat[0] = matA * a + matC * b;
|
|
mat[1] = matB * a + matD * b;
|
|
mat[2] = matA * c + matC * d;
|
|
mat[3] = matB * c + matD * d;
|
|
mat[4] = matA * e + matC * f + matE;
|
|
mat[5] = matB * e + matD * f + matF;
|
|
|
|
return mat;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {!ol.Matrix} mat Matrix.
|
|
* @param {number} translateX1 Translate X1.
|
|
* @param {number} translateY1 Translate Y1.
|
|
* @param {number} scaleX Scale X.
|
|
* @param {number} scaleY Scale Y.
|
|
* @param {number} rotation Rotation.
|
|
* @param {number} translateX2 Translate X2.
|
|
* @param {number} translateY2 Translate Y2.
|
|
* @return {!ol.Matrix} Matrix.
|
|
*/
|
|
ol.matrix.makeTransform = function(mat, translateX1, translateY1,
|
|
scaleX, scaleY, rotation, translateX2, translateY2) {
|
|
ol.matrix.makeIdentity(mat);
|
|
if (translateX1 !== 0 || translateY1 !== 0) {
|
|
ol.matrix.translate(mat, translateX1, translateY1);
|
|
}
|
|
if (scaleX != 1 || scaleY != 1) {
|
|
ol.matrix.scale(mat, scaleX, scaleY);
|
|
}
|
|
if (rotation !== 0) {
|
|
ol.matrix.rotate(mat, rotation);
|
|
}
|
|
if (translateX2 !== 0 || translateY2 !== 0) {
|
|
ol.matrix.translate(mat, translateX2, translateY2);
|
|
}
|
|
return mat;
|
|
};
|
|
|
|
|
|
/**
|
|
* Transforms the given vector with the given matrix storing the resulting,
|
|
* transformed vector into resultVec.
|
|
*
|
|
* @param {ol.Matrix} mat The matrix supplying the transformation.
|
|
* @param {Array.<number>} vec The 2 element vector to transform.
|
|
* @param {Array.<number>} resultVec The 2 element vector to receive the results
|
|
* (may be vec).
|
|
* @return {Array.<number>} return resultVec so that operations can be
|
|
* chained together.
|
|
*/
|
|
ol.matrix.multVec2 = function(mat, vec, resultVec) {
|
|
var x = vec[0], y = vec[1];
|
|
resultVec[0] = mat[0] * x + mat[2] * y + mat[4];
|
|
resultVec[1] = mat[1] * x + mat[3] * y + mat[5];
|
|
return resultVec;
|
|
};
|
|
|
|
|
|
/**
|
|
* Scales the given matrix.
|
|
* @param {!ol.Matrix} mat Matrix.
|
|
* @param {number} sx Scale factor x.
|
|
* @param {number} sy Scale factor y.
|
|
* @return {!ol.Matrix} The scaled matrix.
|
|
*/
|
|
ol.matrix.scale = function(mat, sx, sy) {
|
|
return ol.matrix.transform(mat, sx, 0, 0, sy, 0, 0);
|
|
};
|
|
|
|
|
|
/**
|
|
* Translate the given matrix.
|
|
* @param {!ol.Matrix} mat Matrix.
|
|
* @param {number} tx Translation x.
|
|
* @param {number} ty Translation y.
|
|
* @return {!ol.Matrix} The translated matrix.
|
|
*/
|
|
ol.matrix.translate = function(mat, tx, ty) {
|
|
return ol.matrix.transform(mat, 1, 0, 0, 1, tx, ty);
|
|
};
|
|
|
|
|
|
/**
|
|
* Invert the given matrix.
|
|
* @param {!ol.Matrix} mat Matrix.
|
|
* @param {ol.Matrix=} opt_mat Optional matrix for the result.
|
|
* @return {!ol.Matrix} Inverse of the matrix.
|
|
*/
|
|
ol.matrix.invert = function(mat, opt_mat) {
|
|
var result = opt_mat ? opt_mat : ol.matrix.create();
|
|
var det = ol.matrix.determinant(mat);
|
|
goog.asserts.assert(det !== 0, 'Matrix cannot be inverted.');
|
|
|
|
result[0] = mat[3] / det;
|
|
result[1] = -mat[1] / det;
|
|
result[2] = -mat[2] / det;
|
|
result[3] = mat[0] / det;
|
|
result[4] = (mat[2] * mat[5] - mat[3] * mat[4]) / det;
|
|
result[5] = -(mat[0] * mat[5] - mat[1] * mat[4]) / det;
|
|
return result;
|
|
};
|
|
|
|
|
|
/**
|
|
* Returns the determinant of the given matrix.
|
|
* @param {!ol.Matrix} mat Matrix.
|
|
* @return {number} Determinant.
|
|
*/
|
|
ol.matrix.determinant = function(mat) {
|
|
return mat[0] * mat[3] - mat[1] * mat[2];
|
|
};
|