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>
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>
相关文章推荐
- Decomposing a matrix(用于分解变换矩阵至旋转、平移,缩放分量)
- Decomposing a matrix(用于分解变换矩阵至旋转、平移,缩放分量)
- 怎么将变换矩阵分解为缩放和旋转,尽量不用矩阵表示
- NYOJ 298-点的变换(经典矩阵解决点平移、缩放、翻转和旋转)
- 自定义控件(11)---Canvas的平移、旋转、缩放、错切、Matrix直接变换Canvas
- Android 绘图基础:Bitmap(位图)与Matrix(矩阵)实现图片5种操作(平移、旋转、错切、缩放、对称)
- 图像基本变换--- 平移、旋转、缩放、仿射变换、镜像
- [OpenGL ES 04]3D变换实践篇:平移,旋转,缩放
- 矩阵的旋转平移正变换及反变换
- ios-矩阵旋转缩放平移操作
- 【C#/WPF】Image图片的Transform变换:平移、缩放、旋转
- OpenCV 根据对应的三维点估计刚体变换的旋转平移矩阵(RT矩阵)
- 矩阵的变换。包括缩放、平移、错切
- 【数字图像处理】六.MFC空间几何变换之图像平移、镜像、旋转、缩放详解
- [OpenGL ES 04]3D变换实践篇:平移,旋转,缩放
- Matrix控制平移、旋转和缩放的方法
- 【J2me3D系列学习文章之三】(立即模式)对立方体进行变换操作-旋转、缩放、平移
- 七 iOS之 矩阵操作(图形上下文的平移、缩放、旋转)
- vtkPolyData 的空间变换(平移、旋转、缩放)
- 【数字图像处理】六.MFC空间几何变换之图像平移、镜像、旋转、缩放具体解释