我有一个应用程序,用户点击div来检索其3D方向值,然后我将其映射到3个滑块上。当我用jQuery查找div的CSS转换属性时,我当然只得到内部的matrix3d()。
我可以从2d变换矩阵()中提取值,但3D矩阵超出了我的范围。有人知道可以达到这个目的的配方或库吗?
答案 0 :(得分:1)
由于首选不粘贴链接,我会粘贴w3c页面中的代码css3 transforms
请注意,此伪代码会为您提供四元数,您可以使用其他答案将其转换为角度here
<强> 20.1。分解矩阵
下面的伪代码基于“图形宝石II,由Jim Arvo编辑”中的“unmatrix”方法,但修改为使用四元数而不是欧拉角来避免万向锁的问题。
以下伪代码适用于4x4齐次矩阵:
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分量向量,矩阵是4x4矩阵):
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
分解也使用以下功能:
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
答案 1 :(得分:0)
之前我也有同样的问题,在计算矩阵后我终于得到了这个解决方案(这也适用于矩阵和matrix3d)。
function get_css_transform(obj){
var angle=0,rotateX=0,rotateY=0,rotateZ=0;
var matrix = obj.css("-webkit-transform") ||
obj.css("-moz-transform") ||
obj.css("-ms-transform") ||
obj.css("-o-transform") ||
obj.css("transform");
if(isset(matrix) && matrix !== 'none') {
// if matrix is 2d matrix
if (matrix.indexOf('matrix(')>=0){
var values = matrix.split('(')[1].split(')')[0];
if (is_ie()){ //IE
angle = parseFloat(values.replace('deg', STR_EMPTY));
} else {
values = values.split(',');
var a = values[0];
var b = values[1];
var angle = Math.round(Math.atan2(b, a) * (180/Math.PI));
rotateX=0;
rotateY=0;
rotateZ=0;
}
}else {
// matrix is matrix3d
var values=matrix.split('(')[1].split(')')[0].split(',');
var sinB=parseFloat(values[8]);
var b=Math.round(Math.asin(sinB)*180/Math.PI);
var cosB=Math.cos(b*Math.PI/180);
var matrixVal10=parseFloat(values[9]);
var a=Math.round(Math.asin(-matrixVal10/cosB)*180/Math.PI);
var matrixVal1=parseFloat(values[0]);
var c=Math.round(Math.acos(matrixVal1/cosB)*180/Math.PI);
rotateX=a;
rotateY=b;
rotateZ=c;
}
} else {
angle=0;
rotateX=0;
rotateY=0;
rotateZ=0;
}
return {
angle:angle,
rotateX:rotateX,
rotateY:rotateY,
rotateZ:rotateZ,
};
}