分解旋转矩阵
Posted
技术标签:
【中文标题】分解旋转矩阵【英文标题】:Decomposing a rotation matrix 【发布时间】:2011-01-09 18:44:07 【问题描述】:我有一个旋转矩阵。如何获得围绕该矩阵中包含的指定轴的旋转?
编辑:
这是一个 3D 矩阵 (4x4),我想知道矩阵绕预定(未包含)轴旋转多远。我已经可以分解矩阵,但 D3DX 只会将整个矩阵作为围绕一个轴旋转一次,而我需要将矩阵拆分为围绕已知轴的旋转角度,其余部分。
示例代码和简要问题描述:
D3DXMATRIX CameraRotationMatrix;
D3DXVECTOR3 CameraPosition;
//D3DXVECTOR3 CameraRotation;
inline D3DXMATRIX GetRotationMatrix()
return CameraRotationMatrix;
inline void TranslateCamera(float x, float y, float z)
D3DXVECTOR3 rvec, vec(x, y, z);
#pragma warning(disable : 4238)
D3DXVec3TransformNormal(&rvec, &vec, &GetRotationMatrix());
#pragma warning(default : 4238)
CameraPosition += rvec;
RecomputeVPMatrix();
inline void RotateCamera(float x, float y, float z)
D3DXVECTOR3 RotationRequested(x, y, z);
D3DXVECTOR3 XAxis, YAxis, ZAxis;
D3DXMATRIX rotationx, rotationy, rotationz;
XAxis = D3DXVECTOR3(1, 0, 0);
YAxis = D3DXVECTOR3(0, 1, 0);
ZAxis = D3DXVECTOR3(0, 0, 1);
#pragma warning(disable : 4238)
D3DXVec3TransformNormal(&XAxis, &XAxis, &GetRotationMatrix());
D3DXVec3TransformNormal(&YAxis, &YAxis, &GetRotationMatrix());
D3DXVec3TransformNormal(&ZAxis, &ZAxis, &GetRotationMatrix());
#pragma warning(default : 4238)
D3DXMatrixIdentity(&rotationx);
D3DXMatrixIdentity(&rotationy);
D3DXMatrixIdentity(&rotationz);
D3DXMatrixRotationAxis(&rotationx, &XAxis, RotationRequested.x);
D3DXMatrixRotationAxis(&rotationy, &YAxis, RotationRequested.y);
D3DXMatrixRotationAxis(&rotationz, &ZAxis, RotationRequested.z);
CameraRotationMatrix *= rotationz;
CameraRotationMatrix *= rotationy;
CameraRotationMatrix *= rotationx;
RecomputeVPMatrix();
inline void RecomputeVPMatrix()
D3DXMATRIX ProjectionMatrix;
D3DXMatrixPerspectiveFovLH(
&ProjectionMatrix,
FoV,
(float)D3DDeviceParameters.BackBufferWidth / (float)D3DDeviceParameters.BackBufferHeight,
FarPlane,
NearPlane
);
D3DXVECTOR3 CamLookAt;
D3DXVECTOR3 CamUpVec;
#pragma warning(disable : 4238)
D3DXVec3TransformNormal(&CamLookAt, &D3DXVECTOR3(1, 0, 0), &GetRotationMatrix());
D3DXVec3TransformNormal(&CamUpVec, &D3DXVECTOR3(0, 1, 0), &GetRotationMatrix());
#pragma warning(default : 4238)
D3DXMATRIX ViewMatrix;
#pragma warning(disable : 4238)
D3DXMatrixLookAtLH(&ViewMatrix, &CameraPosition, &(CamLookAt + CameraPosition), &CamUpVec);
#pragma warning(default : 4238)
ViewProjectionMatrix = ViewMatrix * ProjectionMatrix;
D3DVIEWPORT9 vp =
0,
0,
D3DDeviceParameters.BackBufferWidth,
D3DDeviceParameters.BackBufferHeight,
0,
1
;
D3DDev->SetViewport(&vp);
实际上,在调用 RotateCamera 一段时间后,它开始在相对 X 轴上旋转——即使在响应鼠标输入时为该请求传递了常量零,所以我知道在移动鼠标时,相机根本不应该滚动。我尝试发送 0,0,0 个请求并没有看到任何变化(每帧一个,每秒 1500 帧),所以我很确定我没有看到 FP 错误或矩阵累积错误。我尝试编写一个 RotateCameraYZ 函数并从函数中剥离所有 X 轴。我花了几天时间试图找出为什么会这样,并最终决定只是绕过它。
所以我想得到围绕相对x轴的旋转,变换CameraRotation矩阵,然后检查它是否相同,如果不是,添加一个校正矩阵。
仅供参考,我在Wikipedia上看过一些图表,实际上我有一个比较奇怪的轴布局,即Y轴向上,但是X轴向前,Z轴向右,所以Y轴偏航,Z轴俯仰, X 轴滚动。
【问题讨论】:
这对我来说没有多大意义。 2D 还是 3D?矩阵是如何包含轴的? 这是一个3D矩阵(4x4),矩阵不包含轴,我有轴。我想知道矩阵绕这个轴旋转了多远。 @DeadMG 3D 旋转矩阵可以表示为 3x3 矩阵。我在这里仍然没有看到明确定义的问题。如果您提供一些背景知识可能会有所帮助。 @Caspar:不。我想确保在转换之后,它围绕 X 轴的旋转量与转换前完全一样,但对于任何轴,不仅仅是 X。 @Caspar:是的,类似的。 【参考方案1】:请参阅 Wikipedia。警告:提前计算
【讨论】:
以上是关于分解旋转矩阵的主要内容,如果未能解决你的问题,请参考以下文章