РЕДАКТИРОВАТЬ 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 °).В общем случае ни один порядок применения не будет соответствовать базисному преобразованию.
Я исчерпал себя, поэтому я надеюсь, что объяснение до сих пор проясняет ситуацию, а не делает грязнее.