I am trying to write code with rotates an object.

I implemented it as:

Rotation about X-axis is given by the amount of change in y coordinates of a mouse and Rotation about Y-axis is given by the amount of change in x coordinates of a mouse.

This method is simple and work fine until on the the axis coincides with Z-axis, in short a gimble lock occurs.

How can I utilize the rotation arount Z-axis to avoid gimbal lock.

  • \$\begingroup\$ Short answer: use quaternions \$\endgroup\$ – Robert Rouhani Mar 20 '13 at 17:16
  • 6
    \$\begingroup\$ Quaternions are still prone to gimbal lock if you use them wrong - it's not what you use to represent your rotations, it's concatenating multiple rotations that causes it. So don't concatenate rotations. \$\endgroup\$ – Maximus Minimus Mar 20 '13 at 17:27
  • \$\begingroup\$ Regarding my previous comment, see the comment from Maik Semder at gamedev.stackexchange.com/questions/23540/… \$\endgroup\$ – Maximus Minimus Mar 20 '13 at 17:39
  • \$\begingroup\$ I was about to write the same comment again, thanks for finding it @mh01 :) \$\endgroup\$ – Maik Semder Mar 20 '13 at 17:53

The simple solution is not to store the orientation of the object as angles around axes (X-, Y-, Z-axis), as for instance in euler angles.

Store the orientation of the object as a matrix or a quaternion.

This can cause gimbal lock, using euler angles:

class Object
    float m_angleAxisX;
    float m_angleAxisY;
    float m_angleAxisZ;

No gimbal lock:

class Object
    matrix m_orientation;   

No gimbal lock either:

class Object
    quaternion m_orientation;   

Now whenever the mouse is changed, multiply m_orientation with the orientation change coming from the mouse movement each frame.


This book (real-time rendering) helped me alot! See on page 66 and 70. It has very good graphics and explenation. Quaternions are on page 72 aswell! :)

Rotation about an Arbitrary Axis

This renders the camera with the rotation done by mouse input:

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


With the mouse input you modify yaw(head), pitch and roll.

  • 2
    \$\begingroup\$ -1 This does not solve the gimbal lock as it uses euler angles (m_rotation) for the internal orientation storage. This wiki explains why. \$\endgroup\$ – Maik Semder Mar 20 '13 at 20:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.