Как может простой вызов Pitch() и Yaw() привести к тому, что камера в конечном итоге перевернется ()?

StackOverflow https://stackoverflow.com/questions/784445

  •  16-09-2019
  •  | 
  •  

Вопрос

Я пишу базовую игру на OpenGL, и у меня есть некоторый код, который управляет мышью с точки зрения перемещения камеры.

Я использую следующий метод:

int windowWidth = 640;
int windowHeight = 480;

int oldMouseX = -1;
int oldMouseY = -1;

void mousePassiveHandler(int x, int y)
{
    int snapThreshold = 50;

    if (oldMouseX != -1 && oldMouseY != -1)
    {
        cam.yaw((x - oldMouseX)/10.0);
        cam.pitch((y - oldMouseY)/10.0);


        oldMouseX = x;
        oldMouseY = y;

        if ((fabs(x - (windowWidth / 2)) > snapThreshold) || (fabs(y - (windowHeight / 2)) > snapThreshold))
        {
            oldMouseX = windowWidth / 2;
            oldMouseY = windowHeight / 2;
            glutWarpPointer(windowWidth / 2, windowHeight / 2);
        }
    }
    else
    {
        oldMouseX = windowWidth / 2;
        oldMouseY = windowHeight / 2;
        glutWarpPointer(windowWidth / 2, windowHeight / 2);
    }


    glutPostRedisplay();

}

Однако, осмотревшись кругами, вы обнаружите, что камера начинает "катиться" (вращаться).Поскольку я вызываю только тангаж и рыскание, я не понимаю, как это возможно.

Вот код, который я использую для своего класса Camera: http://pastebin.com/m20d2b01e

Насколько я знаю, "закручивания" моей камеры произойти не должно.Он должен просто наклоняться вверх-вниз или рыскать влево-вправо.НЕ катиться.

Что может быть причиной этого?

Это было полезно?

Решение

Поздравляю - вы открыли теорию групп Ли!

Да, это возможно.Результат серии преобразований зависит от порядка, в котором они выполняются.Выполнение подачи с последующим рысканием - это не то же самое, что выполнение рыскания, за которым следует подача.Фактически, в пределе бесконечно малых рысканий и подач разница составляет чистый крен;общие сведения случай немного сложнее.

(Физики называют это "коммутационными соотношениями группы вращения".)

Если вы знакомы с матрицами вращения, вы можете разобраться в этом довольно легко.

Другие советы

Вероятно, вам нужно будет использовать кватернионы для составления вращений, если вы еще этого не делаете.Это позволяет избежать проблемы карданный замок который вы можете получить при ориентации камеры путем вращения вокруг 3 осей.

Вот как конвертировать между ними.

Что ж, если вы начнете смотреть вперед по горизонтали, поднимите угол наклона на 90 градусов, затем отклонитесь влево на 90 градусов, затем опуститесь на 90 градусов, вы будете смотреть в том же направлении, что и начали, но горизонт будет вертикальным (как если бы вы повернули на 90 градусов влево).

Редактировать:Я думаю, проблема в том, что рыскание / тангаж / крен были бы уместны, если бы с камерой обращались как с самолетом.Что вы, вероятно, хотите сделать, так это рассматривать это как точку на сфере, отслеживая, куда на сфере вы наводите камеру.Вместо рыскания / тангажа используйте сферические координаты, отслеживающие тета (широту) и фи (долготу).Они могут звучать похоже, но рассмотрим крайний случай, когда камера направлена прямо вверх.С помощью yaw / pitch вы по-прежнему можете свободно регулировать рыскание и тангаж в этом прямом направлении.С помощью theta / phi вы могли регулировать theta только в сторону уменьшения, и независимо от того, насколько сильно вы отрегулировали phi, уменьшение theta все равно даст вам камеру, расположенную параллельно горизонту.Вот как работает камера с частотой кадров в секунду (вы не можете заглядывать так далеко вниз, чтобы смотреть назад).

Правка 2:Глядя на код камеры, с которым вы связались, вы хотите использовать rotLati(float angle) и rotLongi(float angle) функции.

Математически причина этого заключается в том, что вращения в трехмерном пространстве не коммутируют.Это означает, что pitch(), за которым следует yaw(), - это не то же самое, что yaw(), за которым следует pitch(), но следствием этого факта является то, что три вида поворотов неразрывно связаны, и вы не можете выполнить какие-либо два из них, не выполнив что-то из третьего.Другими словами, любая последовательность действий по тангажу () и рысканию () с течением времени приведет к заметному эффекту крена (), если только вторая половина последовательности не является полной противоположностью первой половине.(В этом задействовано много довольно сложной математики, но детали не особенно важны)

Тангаж / рыскание / крен - все это зависит от ориентации вашего автомобиля.Когда вы наклоняетесь вверх / вниз, вы меняете свою ось рыскания.Аналогично, когда вы отклоняетесь от курса, вы меняете ось тангажа.Таким образом, можно изменить свою ориентацию способом, аналогичным маневру крена, просто комбинируя маневры по тангажу и рысканию.

Я полагаю, что это обстоятельство называется Карданный Замок - на странице Википедии есть пример этого с иллюстрациями.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top