dommetry
Version:
The W3C Geometry Interfaces implemented in JavaScript and polyfilled.
117 lines (99 loc) • 4.57 kB
JavaScript
export
function multiplyToArray(A, B) {
//XXX: Are the following calculations faster hard coded (current), or as a loop?
let m11 = (A.m11 * B.m11) + (A.m21 * B.m12) + (A.m31 * B.m13) + (A.m41 * B.m14)
let m21 = (A.m11 * B.m21) + (A.m21 * B.m22) + (A.m31 * B.m23) + (A.m41 * B.m24)
let m31 = (A.m11 * B.m31) + (A.m21 * B.m32) + (A.m31 * B.m33) + (A.m41 * B.m34)
let m41 = (A.m11 * B.m41) + (A.m21 * B.m42) + (A.m31 * B.m43) + (A.m41 * B.m44)
let m12 = (A.m12 * B.m11) + (A.m22 * B.m12) + (A.m32 * B.m13) + (A.m42 * B.m14)
let m22 = (A.m12 * B.m21) + (A.m22 * B.m22) + (A.m32 * B.m23) + (A.m42 * B.m24)
let m32 = (A.m12 * B.m31) + (A.m22 * B.m32) + (A.m32 * B.m33) + (A.m42 * B.m34)
let m42 = (A.m12 * B.m41) + (A.m22 * B.m42) + (A.m32 * B.m43) + (A.m42 * B.m44)
let m13 = (A.m13 * B.m11) + (A.m23 * B.m12) + (A.m33 * B.m13) + (A.m43 * B.m14)
let m23 = (A.m13 * B.m21) + (A.m23 * B.m22) + (A.m33 * B.m23) + (A.m43 * B.m24)
let m33 = (A.m13 * B.m31) + (A.m23 * B.m32) + (A.m33 * B.m33) + (A.m43 * B.m34)
let m43 = (A.m13 * B.m41) + (A.m23 * B.m42) + (A.m33 * B.m43) + (A.m43 * B.m44)
let m14 = (A.m14 * B.m11) + (A.m24 * B.m12) + (A.m34 * B.m13) + (A.m44 * B.m14)
let m24 = (A.m14 * B.m21) + (A.m24 * B.m22) + (A.m34 * B.m23) + (A.m44 * B.m24)
let m34 = (A.m14 * B.m31) + (A.m24 * B.m32) + (A.m34 * B.m33) + (A.m44 * B.m34)
let m44 = (A.m14 * B.m41) + (A.m24 * B.m42) + (A.m34 * B.m43) + (A.m44 * B.m44)
// in column-major order:
let resultArray = [
m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m31, m31, m31,
m41, m41, m41, m41,
]
return resultArray
}
export
function applyArrayValuesToDOMMatrix(array, matrix) {
let length = array.length
if (length === 6) {
matrix.m11 = array[0]
matrix.m12 = array[1]
matrix.m21 = array[2]
matrix.m22 = array[3]
matrix.m41 = array[4]
matrix.m42 = array[5]
}
else if (length === 16) {
matrix.m11 = array[0]
matrix.m12 = array[1]
matrix.m13 = array[2]
matrix.m14 = array[3]
matrix.m21 = array[4]
matrix.m22 = array[5]
matrix.m23 = array[6]
matrix.m24 = array[7]
matrix.m31 = array[8]
matrix.m32 = array[9]
matrix.m33 = array[10]
matrix.m34 = array[11]
matrix.m41 = array[12]
matrix.m42 = array[13]
matrix.m43 = array[14]
matrix.m44 = array[15]
}
}
export
function matrixToArray(matrix) {
let result = null
if (matrix.is2D) {
result = [
matrix.m11, matrix.m12,
matrix.m21, matrix.m22,
matrix.m41, matrix.m42,
]
}
else {
result = [
matrix.m11, matrix.m12, matrix.m13, matrix.m14,
matrix.m21, matrix.m22, matrix.m23, matrix.m24,
matrix.m31, matrix.m32, matrix.m33, matrix.m34,
matrix.m41, matrix.m42, matrix.m43, matrix.m44,
]
}
return result
}
export
function rotateAxisAngleArray(x, y, z, angle) {
let {sin, cos, pow} = Math
let halfAngle = degreesToRadians(angle/2)
// TODO: should we provide a 6-item array here to signify 2D when the
// rotation is about the Z axis (for example when calling rotateSelf)?
// TODO: angle is supplied in degrees, but Math.* functions use
// radians. Do we need to convert to radians?
// TODO: Performance can be improved by first detecting when x, y, or z of
// the axis are zero or 1, and using a pre-simplified version of the
// folowing math based on that condition.
return [
1-2*(y*y + z*z)*pow(sin(halfAngle), 2), 2*(x*y*pow(sin(halfAngle), 2) + z*sin(halfAngle)*cos(halfAngle)), 2*(x*z*pow(sin(halfAngle), 2) - y*sin(halfAngle)*cos(halfAngle)), 0,
2*(x*y*pow(sin(halfAngle), 2) - z*sin(halfAngle)*cos(halfAngle)), 1-2*(x*x + z*z)*pow(sin(halfAngle), 2), 2*(y*z*pow(sin(halfAngle), 2) + x*sin(halfAngle)*cos(halfAngle)), 0,
2*(x*z*pow(sin(halfAngle), 2) + y*sin(halfAngle)*cos(halfAngle)), 2*(y*z*pow(sin(halfAngle), 2) - x*sin(halfAngle)*cos(halfAngle)), 1-2*(x*x + y*y)*pow(sin(halfAngle), 2), 0,
0, 0, 0, 1,
]
}
function degreesToRadians(degrees) {
return Math.PI/180 * degrees
}