Как всегда вращаться с определенной ориентации - PullRequest
1 голос
/ 22 июля 2010

(Заранее извиняюсь. Мои математические навыки и способности описания, кажется, оставили меня на данный момент) Представьте себе куб на экране с двумя наборами элементов управления. Один набор элементов управления для поворота куба из стороны в сторону (также как рыскание или Y или даже Z в зависимости от математических наклонов) и другой набор элементов управления для поворота вверх и вниз (также известный как шаг или X).

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

Обычная комбинация вращений на основе матрицы или кватерниона не дает этого эффекта, потому что вращения применяются последовательно (с каждым вращением, «начинающимся» с того места, где остановился предыдущий).

например. С кодом псевдо combinatedRotation = RotateYaw(90) * RotatePitch(45) даст мне куб, который, кажется, «катится» в одну сторону, потому что вращение тангажа также было повернуто. (или для более драматического примера RotateYaw(180) * RotatePitch(45) создаст куб, в котором кажется, что поле работает в обратном направлении к экрану)

Может ли кто-нибудь указать мне или предоставить правильный способ сделать два поворота независимыми друг от друга в действительности, чтобы независимо от того, как в данный момент вращается куб, Yaw и Pitch работают «как положено» по отношению к элементам управления на экране

1 Ответ

2 голосов
/ 22 июля 2010

РЕДАКТИРОВАТЬ 3: Мне только что пришло в голову, что приведенное ниже решение, хотя и правильное, излишне сложно.Вы можете добиться того же эффекта, просто умножив матрицу вращения на матрицу ориентации, чтобы вычислить новую ориентацию:

M = R * M

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

(конец редактирования 3)


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

В математических терминах вы начинаете с единичной матрицы следующим образом:

M = [1  0  0  0]
    [0  1  0  0]
    [0  0  1  0]
    [0  0  0  1]

Эта матрица состоит из трех векторов, U, V и W, которые представляют- в мировых координатах - три единичных вектора локальной системы координат вашего объекта:

M = [Ux Vx Wx 0]
    [Uy Vy Wy 0]
    [Uz Vz Wz 0]
    [0  0  0  1]

Если вы хотите повернуть объект, поверните каждый вектор in situ .Другими словами, примените вращение независимо к каждому из U, V и W в матрице.

При рендеринге просто примените M как одиночное преобразование к вашему объекту.(Если вам интересно, не применяйте сами повороты; только матрицу.)

РЕДАКТИРОВАНИЕ 2: (Появляется перед первым редактированием, поскольку оно предоставляет контекст для него.)

Пересматривая этот ответ задолго до того, как он был первоначально опубликован, я понял, что, возможно, я не понял недоразумения, которое может возникнуть у вас относительно того, как применять повороты из каждого элемента управления.

Идея не в том, чтобы накапливать вращение, применяемое каждым элементом управления, а применять их отдельно.Скорее, вам следует применять каждое добавочное вращение (т. Е. Каждый раз, когда один из элементов управления вашего ползунка запускает событие изменения) немедленно к векторам U, V и W.

Чтобы выразить это более конкретно, нескажем: «В общей сложности вертикальное управление переместилось на 47 °, а горизонтальное - на 21 °» и примените их как два больших поворота.Это продемонстрирует ту же проблему, что и ваш вопрос.Вместо этого, скажем, «Вертикальный ползунок только что сдвинулся на 0,23 °», и поверните U, V и W вокруг оси X на 0,23 °.

Короче говоря, поворот на 90 ° с последующим шагом 45 °, описанным нижеэто, вероятно, не то, что вы хотите.

РЕДАКТИРОВАТЬ: В соответствии с просьбой, вот как на практике разворачивается случай поворота на 90 ° с последующим шагом наклона 45 ° ...

Поскольку вы начинаете с матрицы тождеств, базовыми векторами будут просто ваши мировые единичные векторы:

U = [1]  V = [0]  W = [0]
    [0]      [1]      [0]
    [0]      [0]      [1]

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

U = [0]  V = [-1]  W = [0]
    [1]      [ 0]      [0]
    [0]      [ 0]      [1]

Таким образом, после поворота на 90 ° матрица преобразования будет иметь вид:

M = [0 -1  0  0]
    [1  0  0  0]
    [0  0  1  0]
    [0  0  0  1]

Применение этой матрицы к объекту приведет к желаемым 90 °вращение вокруг Z.

Чтобы затем применить шаг 45 ° (который я буду принимать вокруг оси X), мы вращаем наши новые базисные векторы в плоскости YZ, на этот раз на 45 °:

U = [0  ]  V = [-1]  W = [ 0  ]
    [0.7]      [ 0]      [-0.7]
    [0.7]      [ 0]      [ 0.7]

Таким образом, новая матрица преобразования:

M = [0    -1   0    0]
    [0.7   0  -0.7  0]
    [0.7   0   0.7  0]
    [0     0   0    1]

Если выумножив два поворота вместе:

Yaw(90)*Pitch(45) = [0 -1 0 0]*[1  0    0    0] = [0  -0.7  0.7  0]
                    [1  0 0 0] [0  0.7 -0.7  0]   [1   0    0    0]
                    [0  0 1 0] [0  0.7  0.7  0]   [0   0.7  0.7  0]
                    [0  0 0 1] [0  0    0    1]   [0   0    0    1]

Pitch(45)*Yaw(90) = [1  0    0    0]*[0 -1 0 0] = [0    -1   0    0]
                    [0  0.7 -0.7  0] [1  0 0 0]   [0.7   0  -0.7  0]
                    [0  0.7  0.7  0] [0  0 1 0]   [0.7   0   0.7  0]
                    [0  0    0    1] [0  0 0 1]   [0     0   0    1]

Вы заметите, что вторая форма совпадает с матрицей преобразования, созданной путем манипулирования базовыми векторами, но это всего лишь совпадение (и довольно распространенное явление).при смешивании поворотов на 90 ° и 45 °).В общем случае ни один порядок применения не будет соответствовать базисному преобразованию.

Я исчерпал себя, поэтому я надеюсь, что объяснение до сих пор проясняет ситуацию, а не делает грязнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...