您的位置:首页 > 其它

Decomposing a matrix(用于分解变换矩阵至旋转、平移,缩放分量)

2009-12-16 11:59 591 查看
lMatrix: D3DMATRIX;

lRotateMatrix, lTranslationMatrix: D3DMATRIX;

lScaleVec3: TD3DXVector3;

D3DXMatrixIdentity(lRotateMatrix);

D3DXMatrixIdentity(lTranslationMatrix);

//比例为向量的长度。

lScaleVec3.x := D3DXVec3Length(D3DXVector3(lMatrix._11, lMatrix._12, lMatrix._13));

lScaleVec3.y := D3DXVec3Length(D3DXVector3(lMatrix._21, lMatrix._22, lMatrix._23));

lScaleVec3.z := D3DXVec3Length(D3DXVector3(lMatrix._31, lMatrix._32, lMatrix._33));

lRotateMatrix._11 := lMatrix._11 / lScaleVec3.x;

lRotateMatrix._21 := lMatrix._21 / lScaleVec3.y;

lRotateMatrix._31 := lMatrix._31 / lScaleVec3.z;

lRotateMatrix._41 := 0;

lRotateMatrix._12 := lMatrix._12 / lScaleVec3.x;

lRotateMatrix._22 := lMatrix._22 / lScaleVec3.y;

lRotateMatrix._32 := lMatrix._32 / lScaleVec3.z;

lMatrix._42 := 0;

lRotateMatrix._13 := lMatrix._13 / lScaleVec3.x;

lRotateMatrix._23 := lMatrix._23 / lScaleVec3.y;

lRotateMatrix._33 := lMatrix._33 / lScaleVec3.z;

lMatrix._43 := 0;

lTranslationMatrix._41 := lTranslationMatrix._41;

lTranslationMatrix._42 := lTranslationMatrix._42;

lTranslationMatrix._43 := lTranslationMatrix._43;

// D3DXMatrixDecompose(@lScaleMatrix, @lRotateMatrix, @lTranslationMatrix, lMatrix);

/************************************************************************************/

D3DXMatrixIdentity(lMatrix);

D3DXMatrixIdentity(lRotateMatrix);

D3DXMatrixIdentity(lTranslationMatrix);

lScaleVec3 := D3DXVector3(0.5, 200, 100);

D3DXMatrixRotationYawPitchRoll(lRotateMatrix, 0.6, 0.3, 0);

lMatrix._11 := lRotateMatrix._11 * lScaleVec3.x;

lMatrix._21 := lRotateMatrix._21 * lScaleVec3.y;

lMatrix._31 := lRotateMatrix._31 * lScaleVec3.z;

lMatrix._41 := 0;

lMatrix._12 := lRotateMatrix._12 * lScaleVec3.x;

lMatrix._22 := lRotateMatrix._22 * lScaleVec3.y;

lMatrix._32 := lRotateMatrix._32 * lScaleVec3.z;

lMatrix._42 := 0;

lMatrix._13 := lRotateMatrix._13 * lScaleVec3.x;

lMatrix._23 := lRotateMatrix._23 * lScaleVec3.y;

lMatrix._33 := lRotateMatrix._33 * lScaleVec3.z;

lMatrix._43 := 0;

lMatrix._41 := lTranslationMatrix._41;

lMatrix._42 := lTranslationMatrix._42;

lMatrix._43 := lTranslationMatrix._43;

end;

Matrix decomposition is very useful when you would like to get the translation, scale or rotation from a matrix. This should not be done very often however since it is an expensive operation.

Here is a Matrix Decomposition function declaration

Parameters: const Matrix& mat

The input matrix to decompose into its translation, scale and rotation elements

Vector3& vTrans

The output decomposed translation Vector

Vector3& vScale

The output decomposed scale Vector

Matrix4& mRot

The output decomposed rotation Matrix

inline void MatrixDecompose(const Matrix4& mat,
Vector3& vTrans,
Vector3& vScale,
Matrix4& mRot)
{

Retrieving the translation is as easy as getting the x,y,z values from the thrid row:

vTrans.x = mat.m_val[3][0];
vTrans.y = mat.m_val[3][1];
vTrans.z = mat.m_val[3][2];

We create a temporary Vector3 array to store the 3x3 matrix that contains the scaling and rotation. We will then take this information and seperate it into its scale and rotation components.

Vector3 vCols[3] = {
Vector3(mat.m_val[0][0],mat.m_val[0][1],mat.m_val[0][2]),
Vector3(mat.m_val[1][0],mat.m_val[1][1],mat.m_val[1][2]),
Vector3(mat.m_val[2][0],mat.m_val[2][1],mat.m_val[2][2])
};

Retrieving the scale is done by gathering the legnth of the vectors for each column of the 3x3 matrix.

vScale.x = vCols[0].Length();
vScale.y = vCols[1].Length();
vScale.z = vCols[2].Length();

The 3x3 rotation matrix can be obtained by dividing each column of the 3x3 rotation/scale matrix by the retrieved scalar component:

if(vScale.x != 0)
{
vCols[0].x /= vScale.x;
vCols[0].y /= vScale.x;
vCols[0].z /= vScale.x;
}
if(vScale.y != 0)
{
vCols[1].x /= vScale.y;
vCols[1].y /= vScale.y;
vCols[1].z /= vScale.y;
}
if(vScale.z != 0)
{
vCols[2].x /= vScale.z;
vCols[2].y /= vScale.z;
vCols[2].z /= vScale.z;
}

//unroll the loop to increase the speed

/*for(int x=0;x<3;x++)
{
mRot.m_val[0][x] = vCols[x].x;
mRot.m_val[1][x] = vCols[x].y;
mRot.m_val[2][x] = vCols[x].z;
mRot.m_val[x][3] = 0;
mRot.m_val[3][x] = 0;
}*/
mRot.m_val[0][0] = vCols[0].x;
mRot.m_val[1][0] = vCols[0].y;
mRot.m_val[2][0] = vCols[0].z;
mRot.m_val[0][3] = 0;
mRot.m_val[3][0] = 0;
mRot.m_val[0][1] = vCols[1].x;
mRot.m_val[1][1] = vCols[1].y;
mRot.m_val[2][1] = vCols[1].z;
mRot.m_val[1][3] = 0;
mRot.m_val[3][1] = 0;
mRot.m_val[0][2] = vCols[2].x;
mRot.m_val[1][2] = vCols[2].y;
mRot.m_val[2][2] = vCols[2].z;
mRot.m_val[2][3] = 0;
mRot.m_val[3][2] = 0;
mRot.m_val[3][3] = 1;
}

源文档 <http://blog.csdn.net/GISsirclyx/archive/2009/10/26/4730543.aspx>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐