惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
博客园 - 【当耐特】
量子位
Engineering at Meta
Engineering at Meta
博客园_首页
大猫的无限游戏
大猫的无限游戏
IT之家
IT之家
V
Visual Studio Blog
小众软件
小众软件
阮一峰的网络日志
阮一峰的网络日志
美团技术团队
Jina AI
Jina AI
The Cloudflare Blog
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
宝玉的分享
宝玉的分享
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
博客园 - 聂微东

博客园 - 蜗牛的天空

技术 - 蜗牛的天空 - 博客园 Visual C#.Net 网络程序开发-Socket篇 关于Smart Client更新的极难问题 User Interface Process 中文使用手册(三)(本程序代码是在.Net2005开发的) - 蜗牛的天空 User Interface Process 中文使用手册(二) User Interface Process 中文使用手册(一) C# Socket编程 C#.Net网络程序开发-Socket篇 学习NET遇到的问题 一个常见的数据库连接的问题???????????? - 蜗牛的天空 - 博客园 命令行环境学习C#指南 问题:救命呀 Windows 服务应用程序 程序集 将 Web 窗体页转换为用户控件 Page属性解释 向 Web 窗体页的“HTML”视图添加用户控件 使用 Visual C# 创作用户控件 在 Web 应用程序中使用 SQL Server
Decomposing a matrix(用于分解变换矩阵至旋转、平移,缩放分量)
蜗牛的天空 · 2009-12-16 · via 博客园 - 蜗牛的天空

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>