【问题标题】: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:是的,类似的。

标签: direct3d trigonometry


【解决方案1】:

请参阅 Wikipedia
警告:提前计算

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 2019-02-08
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多