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.