ジンバルロックを回避する方法


8

オブジェクトを回転させるコードを記述しようとしています。

私はそれを次のように実装しました:

X軸を中心とした回転は、マウスのy座標の変化量によって与えられ、Y軸を中心とした回転は、マウスのx座標の変化量によって与えられます。

この方法は単純で、軸がZ軸と一致するまで、つまりジンバルロックが発生するまでうまく機能します。

ジンバルロックを回避するためにZ軸周りの回転をどのように利用できますか?


短い答え:四元数を
Robert Rouhani

4
クォータニオンは、誤って使用するとジンバルロックを起こしやすくなります。回転を表すために使用するものではなく、複数の回転を連結することによって発生します。したがって、ローテーションを連結しないでください。
Maximus Minimus

私の以前のコメントについて、ではMaik Semderからのコメントを参照してくださいgamedev.stackexchange.com/questions/23540/...
マクシムスMINIMUS

@ mh01を見つけてくれてありがとう:)
Maik Semder

回答:


14

単純な解決策は、たとえばオイラー角のように、オブジェクトの方向を軸(X、Y、Z軸)の周りの角度として保存しないことです。

オブジェクトの方向を行列または四元数として保存します。

これにより、オイラー角を使用してジンバルロックが発生する可能性があります。

class Object
{
    float m_angleAxisX;
    float m_angleAxisY;
    float m_angleAxisZ;
};

ジンバルロックなし:

class Object
{
    matrix m_orientation;   
};

ジンバルロックなし:

class Object
{
    quaternion m_orientation;   
};

これで、マウスが変更されるたびに、m_orientationに、各フレームのマウスの動きによる方向の変更を乗算します。


0

この本(リアルタイムレンダリング)は私を大いに助けてくれました!66ページと70ページを参照してください。グラフィックと説明が非常に優れています。四元数も72ページにあります!:)

任意の軸を中心とした回転

これにより、マウス入力によって行われた回転でカメラがレンダリングされます。

void Camera::getVectors(D3DXVECTOR3& up, D3DXVECTOR3& lookAt)
{
    float yaw, pitch, roll;
    D3DXMATRIX rotationMatrix;

    // Setup the vector that points upwards.
    up.x = 0.0f;
    up.y = 1.0f;
    up.z = 0.0f;

    // Setup where the camera is looking by default.
    lookAt.x = 0.0f;
    lookAt.y = 0.0f;
    lookAt.z = 1.0f;

    // Set the yaw (Y axis), pitch (X axis), and roll (Z axis) rotations in radians.
    pitch = m_rotation.x * 0.0174532925f;
    yaw   = m_rotation.y * 0.0174532925f;
    roll  = m_rotation.z * 0.0174532925f;

    // Create the rotation matrix from the yaw, pitch, and roll values.
    D3DXMatrixRotationYawPitchRoll(&rotationMatrix, yaw, pitch, roll);

    // Transform the lookAt and up vector by the rotation matrix so the view is correctly rotated at the origin.
    D3DXVec3TransformCoord(&lookAt, &lookAt, &rotationMatrix);
    D3DXVec3TransformCoord(&up, &up, &rotationMatrix);
}

// The Render function uses the position and rotation of the camera to build and update the view matrix
void Camera::render()
{
    D3DXVECTOR3 up, position, lookAt;

    // Setup the position of the camera in the world.
    position = (D3DXVECTOR3)m_position;

    getVectors(up, lookAt);

    // Translate the rotated camera position to the location of the viewer.
    lookAt = position + lookAt;

    // Finally create the view matrix from the three updated vectors.
    D3DXMatrixLookAtLH(&m_viewMatrix, &position, &lookAt, &up);

    return;
}

マウス入力を使用して、ヨー(ヘッド)、ピッチ、ロールを変更します。


1
-1内部方向の格納にオイラー角(m_rotation)を使用するため、これはジンバルロックを解決しません。このウィキはその理由を説明しています。
Maik Semder 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.