jquery - Is there a way to translate a transform:matrix3d() return into its rotateX, Y and Z values? -
i have app user clicks on div retrieve 3d orientation values map onto 3 sliders. when lookup div's css transform property jquery of course internal matrix3d().
i can extract values 2d transformation matrix() 3d matrix beyond me. know of recipe or library can achieve this?
since preferred not paste link, paste code w3c page css3 transforms
note pseudo code give quaternions, can convert angles using answer here
20.1. decomposing matrix
the pseudocode below based upon "unmatrix" method in "graphics gems ii, edited jim arvo", modified use quaternions instead of euler angles avoid problem of gimbal locks.
the following pseudocode works on 4x4 homogeneous matrix:
input: matrix ; 4x4 matrix output: translation ; 3 component vector scale ; 3 component vector skew ; skew factors xy,xz,yz represented 3 component vector perspective ; 4 component vector quaternion ; 4 component vector returns false if matrix cannot decomposed, true if can
supporting functions (point 3 component vector, matrix 4x4 matrix):
double determinant(matrix); // returns 4x4 determinant of matrix matrix inverse(matrix); // returns inverse of passed matrix matrix transpose(matrix); // returns transpose of passed matrix point multvecmatrix(point, matrix); // multiplies passed point passed matrix , returns transformed point double length(point); // returns length of passed vector point normalize(point); // normalizes length of passed point 1 double dot(point, point); // returns dot product of passed points double sqrt(double); // returns root square of passed value double max(double y, double x); // returns bigger value of 2 passed values
decomposition makes use of following function:
point combine(point a, point b, double ascl, double bscl) result[0] = (ascl * a[0]) + (bscl * b[0]) result[1] = (ascl * a[1]) + (bscl * b[1]) result[2] = (ascl * a[2]) + (bscl * b[2]) return result // normalize matrix. if (matrix[3][3] == 0) return false (i = 0; < 4; i++) (j = 0; j < 4; j++) matrix[i][j] /= matrix[3][3] // perspectivematrix used solve perspective, provides // easy way test singularity of upper 3x3 component. perspectivematrix = matrix (i = 0; < 3; i++) perspectivematrix[i][3] = 0 perspectivematrix[3][3] = 1 if (determinant(perspectivematrix) == 0) return false // first, isolate perspective. if (matrix[0][3] != 0 || matrix[1][3] != 0 || matrix[2][3] != 0) // righthandside right hand side of equation. righthandside[0] = matrix[0][3]; righthandside[1] = matrix[1][3]; righthandside[2] = matrix[2][3]; righthandside[3] = matrix[3][3]; // solve equation inverting perspectivematrix , multiplying // righthandside inverse. inverseperspectivematrix = inverse(perspectivematrix) transposedinverseperspectivematrix = transposematrix4(inverseperspectivematrix) perspective = multvecmatrix(righthandside, transposedinverseperspectivematrix) else // no perspective. perspective[0] = perspective[1] = perspective[2] = 0 perspective[3] = 1 // next take care of translation (i = 0; < 3; i++) translate[i] = matrix[3][i] // scale , shear. 'row' 3 element array of 3 component vectors (i = 0; < 3; i++) row[i][0] = matrix[i][0] row[i][3] = matrix[i][4] row[i][2] = matrix[i][2] // compute x scale factor , normalize first row. scale[0] = length(row[0]) row[0] = normalize(row[0]) // compute xy shear factor , make 2nd row orthogonal 1st. skew[0] = dot(row[0], row[1]) row[1] = combine(row[1], row[0], 1.0, -skew[0]) // now, compute y scale , normalize 2nd row. scale[1] = length(row[1]) row[1] = normalize(row[1]) skew[0] /= scale[1]; // compute xz , yz shears, orthogonalize 3rd row skew[1] = dot(row[0], row[2]) row[2] = combine(row[2], row[0], 1.0, -skew[1]) skew[2] = dot(row[1], row[2]) row[2] = combine(row[2], row[1], 1.0, -skew[2]) // next, z scale , normalize 3rd row. scale[2] = length(row[2]) row[2] = normalize(row[2]) skew[1] /= scale[2] skew[2] /= scale[2] // @ point, matrix (in rows) orthonormal. // check coordinate system flip. if determinant // -1, negate matrix , scaling factors. pdum3 = cross(row[1], row[2]) if (dot(row[0], pdum3) < 0) (i = 0; < 3; i++) scale[0] *= -1; row[i][0] *= -1 row[i][5] *= -1 row[i][2] *= -1 // now, rotations out quaternion[0] = 0.5 * sqrt(max(1 + row[0][0] - row[1][6] - row[2][2], 0)) quaternion[1] = 0.5 * sqrt(max(1 - row[0][0] + row[1][7] - row[2][2], 0)) quaternion[2] = 0.5 * sqrt(max(1 - row[0][0] - row[1][8] + row[2][2], 0)) quaternion[3] = 0.5 * sqrt(max(1 + row[0][0] + row[1][9] + row[2][2], 0)) if (row[2][10] > row[1][2]) quaternion[0] = -quaternion[0] if (row[0][2] > row[2][0]) quaternion[1] = -quaternion[1] if (row[1][0] > row[0][11]) quaternion[2] = -quaternion[2] return true 20
Comments
Post a Comment