是否有一种方法来转换转换:matrix3d()返回到其rotateX,Y和Z值? [英] Is there a way to translate a transform:matrix3d() return into its rotateX, Y and Z values?

查看:107
本文介绍了是否有一种方法来转换转换:matrix3d()返回到其rotateX,Y和Z值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,用户点击div来检索其3D方向值,然后映射到3个滑块。当我使用jQuery查找div的CSS变换属性时,我当然只得到内部的matrix3d()。

I have an app where the user clicks on a div to retrieve its 3D orientation values that I then map onto 3 sliders. When I lookup the div's CSS transform property with jQuery I of course only get the internal matrix3d().

我可以从2d变换矩阵3D矩阵超越我。

I can extract the values from a 2d transformation matrix() but a 3D matrix is beyond me. Does anybody know of a recipe or library that can achieve this?

推荐答案

因为它不是只粘贴一个链接,粘贴w3c页面的代码 css3 transforms

Since it is preferred not to paste just a link, I paste the code from the w3c page css3 transforms

请注意,此伪代码将提供四元数,您可以使用另一个答案将其转换为角度此处

Note that this pseudo code will give you quaternions, you can convert that to angles using another answer here

20.1。分解矩阵

下面的伪代码基于Graphics Gems II,Jim Arvo编辑中的unmatrix方法,但修改为使用四元数而不是欧拉角,以避免Gimbal Locks的问题。

The pseudocode below is based upon the "unmatrix" method in "Graphics Gems II, edited by Jim Arvo", but modified to use Quaternions instead of Euler angles to avoid the problem of Gimbal Locks.

以下伪代码在4x4同构矩阵上工作:

The following pseudocode works on a 4x4 homogeneous matrix:

Input:  matrix      ; a 4x4 matrix
Output: translation ; a 3 component vector
        scale       ; a 3 component vector
        skew        ; skew factors XY,XZ,YZ represented as a 3 component vector
        perspective ; a 4 component vector
        quaternion  ; a 4 component vector
Returns false if the matrix cannot be decomposed, true if it can

支持函数(点是一个3分量矢量,矩阵是一个4×4矩阵):

Supporting functions (point is a 3 component vector, matrix is a 4x4 matrix):

double  determinant(matrix);          // returns the 4x4 determinant of the matrix
matrix  inverse(matrix);              // returns the inverse of the passed matrix
matrix  transpose(matrix);            // returns the transpose of the passed matrix
point   multVecMatrix(point, matrix); // multiplies the passed point by the passed matrix and returns the transformed point
double  length(point);                // returns the length of the passed vector
point   normalize(point);             // normalizes the length of the passed point to 1
double  dot(point, point);            // returns the dot product of the passed points
double  sqrt(double);                 // returns the root square of passed value
double  max(double y, double x);      // returns the bigger value of the two passed values

分解也使用以下函数: / p>

Decomposition also makes use of the 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 the matrix.
if (matrix[3][3] == 0)
    return false

for (i = 0; i < 4; i++)
    for (j = 0; j < 4; j++)
        matrix[i][j] /= matrix[3][3]

// perspectiveMatrix is used to solve for perspective, but it also provides
// an easy way to test for singularity of the upper 3x3 component.
perspectiveMatrix = matrix

for (i = 0; i < 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 is the right hand side of the equation.
    rightHandSide[0] = matrix[0][3];
    rightHandSide[1] = matrix[1][3];
    rightHandSide[2] = matrix[2][3];
    rightHandSide[3] = matrix[3][3];

    // Solve the equation by inverting perspectiveMatrix and multiplying
    // rightHandSide by the 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
for (i = 0; i < 3; i++)
    translate[i] = matrix[3][i]

// Now get scale and shear. 'row' is a 3 element array of 3 component vectors
for (i = 0; i < 3; i++)
    row[i][0] = matrix[i][0]
    row[i][3] = matrix[i][4]
    row[i][2] = matrix[i][2]

// Compute X scale factor and normalize first row.
scale[0] = length(row[0])
row[0] = normalize(row[0])

// Compute XY shear factor and make 2nd row orthogonal to 1st.
skew[0] = dot(row[0], row[1])
row[1] = combine(row[1], row[0], 1.0, -skew[0])

// Now, compute Y scale and normalize 2nd row.
scale[1] = length(row[1])
row[1] = normalize(row[1])
skew[0] /= scale[1];

// Compute XZ and 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, get Z scale and normalize 3rd row.
scale[2] = length(row[2])
row[2] = normalize(row[2])
skew[1] /= scale[2]
skew[2] /= scale[2]

// At this point, the matrix (in rows) is orthonormal.
// Check for a coordinate system flip.  If the determinant
// is -1, then negate the matrix and the scaling factors.
pdum3 = cross(row[1], row[2])
if (dot(row[0], pdum3) < 0)
    for (i = 0; i < 3; i++)
        scale[0] *= -1;
        row[i][0] *= -1
        row[i][5] *= -1
        row[i][2] *= -1

// Now, get the 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

这篇关于是否有一种方法来转换转换:matrix3d()返回到其rotateX,Y和Z值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆