Comment éviter le verrouillage du cardan

8

J'essaie d'écrire du code avec tourne un objet.

Je l'ai implémenté comme:

La rotation autour de l'axe X est donnée par la quantité de changement dans les coordonnées y d'une souris et la rotation autour de l'axe Y est donnée par la quantité de changement dans les coordonnées x d'une souris.

Cette méthode est simple et fonctionne très bien jusqu'à ce que l'axe coïncide avec l'axe Z, bref un blocage de gimble se produit.

Comment puis-je utiliser l'axe de rotation autour de l'axe Z pour éviter le blocage du cardan.

singingsingh
la source
Réponse courte: utilisez des quaternions
Robert Rouhani
4
Les quaternions sont toujours sujets au verrouillage du cardan si vous les utilisez mal - ce n'est pas ce que vous utilisez pour représenter vos rotations, c'est la concaténation de plusieurs rotations qui en est la cause. Ne concaténez donc pas les rotations.
Maximus Minimus
Concernant mon commentaire précédent, voir le commentaire de Maik Semder sur gamedev.stackexchange.com/questions/23540/…
Maximus Minimus
J'étais sur le point d'écrire à nouveau le même commentaire, merci de l'avoir trouvé @ mh01 :)
Maik Semder

Réponses:

14

La solution simple est de ne pas stocker l'orientation de l'objet sous forme d'angles autour des axes (axes X, Y, Z), comme par exemple dans les angles d'Euler.

Stockez l'orientation de l'objet sous forme de matrice ou de quaternion.

Cela peut provoquer un blocage du cardan, en utilisant des angles euler:

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

Pas de verrouillage de cardan:

class Object
{
    matrix m_orientation;   
};

Pas de verrouillage de cardan non plus:

class Object
{
    quaternion m_orientation;   
};

Maintenant, chaque fois que la souris est changée, multipliez m_orientation avec le changement d'orientation provenant du mouvement de la souris à chaque image.

Maik Semder
la source
0

Ce livre (rendu en temps réel) m'a beaucoup aidé! Voir page 66 et 70. Il a de très bons graphiques et explications. Les quaternions sont également à la page 72! :)

Rotation autour d'un axe arbitraire

Cela rend la caméra avec la rotation effectuée par la souris:

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;
}

Avec l'entrée de la souris, vous modifiez le lacet (tête), le tangage et le roulis.

Jinxi
la source
1
-1 Cela ne résout pas le verrouillage du cardan car il utilise des angles d'Euler (m_rotation) pour le stockage d'orientation interne. Ce wiki explique pourquoi.
Maik Semder