Come evitare il blocco del gimbal


8

Sto cercando di scrivere il codice con ruota un oggetto.

L'ho implementato come:

La rotazione attorno all'asse X è data dalla quantità di cambiamento nelle coordinate y di un mouse e La rotazione intorno all'asse X è data dalla quantità di cambiamento nelle coordinate x di un mouse.

Questo metodo è semplice e funziona bene fino a quando l'asse non coincide con l'asse Z, in breve si verifica un blocco del gimble.

Come posso utilizzare la rotazione attorno all'asse Z per evitare il blocco del gimbal.


Risposta breve: usa i quaternioni
— Robert Rouhani,

4
I quaternioni sono ancora inclini al blocco del gimbal se li usi in modo errato - non è quello che usi per rappresentare le tue rotazioni, ma sta concatenando più rotazioni che lo causano. Quindi non concatenare le rotazioni.
— Maximus Minimus

Per quanto riguarda il mio commento precedente, vedi il commento di Maik Semder su gamedev.stackexchange.com/questions/23540/…
— Maximus

Stavo per scrivere di nuovo lo stesso commento, grazie per averlo trovato @ mh01 :)
— Maik Semder

Risposte:


14

La soluzione semplice non è quella di memorizzare l'orientamento dell'oggetto come angoli attorno agli assi (asse X, Y, Z), come ad esempio negli angoli di eulero.

Memorizza l'orientamento dell'oggetto come matrice o quaternione.

Ciò può causare il blocco del gimbal, utilizzando gli angoli di eulero:

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

Nessun blocco del gimbal:

class Object
{
    matrix m_orientation;   
};

Nessun blocco del gimbal:

class Object
{
    quaternion m_orientation;   
};

Ora, ogni volta che si cambia il mouse, moltiplicare m_orientation con il cambio di orientamento proveniente dal movimento del mouse per ogni fotogramma.


0

Questo libro (rendering in tempo reale) mi ha aiutato molto! Vedere a pagina 66 e 70. Ha una grafica e spiegazioni molto buone. I quaternioni sono anche a pagina 72! :)

Rotazione attorno ad un asse arbitrario

Questo rende la telecamera con la rotazione eseguita dall'input del mouse:

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

Con l'input del mouse si modificano imbardata (testa), beccheggio e rollio.


1
-1 Questo non risolve il blocco del gimbal in quanto utilizza gli angoli di eulero (m_rotation) per la memorizzazione dell'orientamento interno. Questa wiki spiega perché.
— Maik Semder,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.