Làm thế nào để tránh khóa gimbal


8

Tôi đang cố gắng viết mã với xoay một đối tượng.

Tôi đã thực hiện nó như:

Xoay quanh trục X được cho bởi số lượng thay đổi trong tọa độ y của chuột và Xoay quanh trục Y được cho bởi số lượng thay đổi trong tọa độ x của chuột.

Phương pháp này đơn giản và hoạt động tốt cho đến khi trên trục trùng với trục Z, trong ngắn hạn xảy ra khóa gimble.

Làm cách nào tôi có thể sử dụng trục xoay quanh trục Z để tránh khóa gimbal.


Câu trả lời ngắn: sử dụng tứ phương
Robert Rouhani

4
Đệ tứ vẫn có xu hướng khóa gimbal nếu bạn sử dụng sai - đó không phải là những gì bạn sử dụng để thể hiện các phép quay của mình, nó kết hợp nhiều phép quay gây ra nó. Vì vậy, đừng xoay vòng xoay.
Maximus Minimus

Về nhận xét trước đây của tôi, hãy xem nhận xét từ Maik Semder tại gamedev.stackexchange.com/questions/23540/ợi
Maximus Minimus 20/03/13

Tôi chuẩn bị viết cùng một bình luận một lần nữa, cảm ơn vì đã tìm thấy nó @ mh01 :)
Maik Semder 20/03/13

Câu trả lời:


14

Giải pháp đơn giản là không lưu trữ hướng của đối tượng dưới dạng các góc xung quanh trục (trục X, Y-, trục Z), ví dụ như trong các góc euler.

Lưu trữ hướng của đối tượng dưới dạng ma trận hoặc bậc bốn.

Điều này có thể gây ra khóa gimbal, sử dụng góc euler:

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

Không có khóa gimbal:

class Object
{
    matrix m_orientation;   
};

Không có khóa gimbal:

class Object
{
    quaternion m_orientation;   
};

Bây giờ bất cứ khi nào chuột được thay đổi, hãy nhân m_orientation với thay đổi hướng đến từ chuyển động chuột của từng khung.


0

Cuốn sách này (kết xuất thời gian thực) đã giúp tôi rất nhiều! Xem ở trang 66 và 70. Nó có đồ họa và khám phá rất tốt. Đệ tứ đang ở trang 72 cũng vậy! :)

Xoay về một trục tùy ý

Điều này làm cho máy ảnh quay với thực hiện bằng cách nhập chuột:

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

Với đầu vào chuột, bạn sửa đổi ngáp (đầu), cao độ và cuộn.


1
-1 Điều này không giải quyết được khóa gimbal vì nó sử dụng các góc euler (m_rotation) cho bộ lưu trữ định hướng bên trong. Wiki này giải thích tại sao.
Maik
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.