分解旋转矩阵

时间:2011-01-09 18:44:08

标签: direct3d trigonometry

我有一个旋转矩阵。如何围绕此矩阵中包含的指定轴进行旋转?

编辑:

这是一个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矩阵,然后检查它以确认它是否相同,如果不相同,则添加一个校正矩阵。

仅供参考,我在维基百科上看到了一些图表,我实际上有一个相对奇怪的轴布局,即Y轴向上,但X轴向前,Z轴向右,所以Y轴偏航,Z轴俯仰, X轴滚动。

1 个答案:

答案 0 :(得分:0)

请参阅Wikipedia 警告:提前数学