XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
inquiro

offline
Опыт: 721
Активность:
Кватернион вращения
Может ли кто-нибудь доходчиво объяснить, что из себя представляет кватернион вращения и как можно его рассчитать (по каким формулам), исходя из угла поворота вокруг осей?

Отредактировано inquiro, 27.11.2006 в 12:09.
Старый 27.11.2006, 10:38
Алексей
Где кошачья мята?!
offline
Опыт: 26,303
Активность:
И как этот вопрос относится к Warcraft'у?
Это скорее по 3D-графике.
Кстати, в сети полно информации по кватернионам (хотя вся она, похоже, заимствована из одного источника - перевода Demo.Design FAQ, т.ч. там полно ошибок).
Кватернион это (если не вдаваться в математические подробности) просто 4D-вектор:
q=(x; y; z; w),
подобранный так, что x*x+y*y+z*z+w*w=1 (это т.н. нормированный кватернион - именно их обычно и используют).
Его можно также условно разбить на два компонента: векторный - v=(x; y; z) и скалярный - w.
Чем удобен кватернион? Да тем, что позволяет очень просто работать с вращениями. Например, все операции с матрицами крайне ресурсоёмки (чего стоит, к примеру, нахождение обратной матрицы поворота!), а работа с углами Эйлера - вообще самый ненадёжный способ представления вращения.
.
Новички чаще всего (по себе знаю!) в своих программах реализуют вращение с помощью углов Эйлера - т.е. простых поворотов вокруг осей x,y,z. В "профессиональных" играх такой подход не используется, т.к.:
  1. Результат зависит от порядка вращения (т.е. если менять порядок следования осей, то результаты будут различны);
  2. Очень трудно вычислить углы поворота, переводящего "взгляд" камеры из позиции A в позицию B. Например, требуется сделать плавную анимацию - поворот объекта. Простым плавным изменением углов тут не обойдёшься: в большинстве случаев подобные развороты будут выглядеть неестественно, камера ведёт себя "неправильно" - не так, как ожидает программист. Некоторые трятят часы, пытаясь понять, почему всё работает не так, как надо.
Тут можно посоветовать лишь отказаться от углов Эйлера.
.
Кватернион задаёт поворот не вокруг осей x,y,z, а вокруг любой, ПРОИЗВОЛЬНОЙ оси.
Итак, если нужно повернуть сцену вокруг некоторого вектора с координатами (x;y;z) на угол A, то кватернион, осуществляющий такой поворот, можно вычислить так:
q.x=x*Sin(A/2)
q.y=y*Sin(A/2)
q.z=z*Sin(A/2)
q.w=Cos(A/2)

Только потом важно не забыть нормировать кватернион - т.е. сделать так, чтобы выполнялось вышеуказанное правило - x*x+y*y+z*z+w*w=1
Это можно сделать, например, так:
n=1/sqrt(q.x*q.x+q.y*q.y+q.z*q.z+q.w*q.w)
q.x=q.x*n
q.y=q.y*n
q.z=q.z*n
q.w=q.w*n

Кватернионы хороши тем, что с ними очень легко работать. Например, их можно складывать (покомпонентно). Сумма кватернионов - это "смесь" тех поворотов, которые они задают. Т.е. конечный кватернион будет представлять некий усреднённый поворот. Кватернионы, как и матрицы, можно перемножать. Допустим, объект нужно повернуть сперва с помощью кватерниона A, затем - с помощью кватерниона B. Тогда поворот можно осуществить одной операцией, повернув объект кватернионом C=A*B. Произведение кватернионов не коммутативно, т.е. AB не равно BA.
Перемножение кватернионов описывается довольно сложной формулой, но есть способы его ускорить - в сети полно "быстрых" методов умножения кватернионов. Вот, например, так можно вычислить произведение q1*q2:
Код:
A=(q1.w+q1.x)*(q2.w+q2.x)
B=(q1.z-q1.y)*(q2.y-q2.z)
C=(q1.x-q1.w)*(q2.y+q2.z)
D=(q1.y+q1.z)*(q2.x-q2.w)
E=(q1.x+q1.z)*(q2.x+q2.y)
F=(q1.x-q1.z)*(q2.x-q2.y)
G=(q1.w+q1.y)*(q2.w-q2.z)
H=(q1.w-q1.y)*(q2.w+q2.z)

result.w= B + (-E - F + G + H) * 0.5
result.x= A - ( E + F + G + H) * 0.5
result.y=-C + ( E - F + G - H) * 0.5
result.z=-D + ( E - F - G + H) * 0.5

Метод кажется очень громоздким, т.к. требует от процессора выполнения 12 умножений и 35 сложений. Однако единственная альтернатива - перемножение матриц поворота - требует 27 умножений и 18 сложений. Учитывая, что на операцию сложения (и вычитания, которая тоже считается сложением ;) процессор тратит всего 1 такт, а умножение осуществляется за 4 такта, перемножение кватернионов будет быстрее умножения матриц (83 такта против 126 тактов).
Более того: из этих 12 перемножений здесь есть 4 умножения на 0.5, которые вычисляются тоже за 1 такт. В результате перемножения нормированных кватернионов всегда получается нормированный кватернион.
.
Ну, а теперь - чуть ближе к сути вопроса. Допустим, нам нужно сперва повернуть объект вокруг оси X на угол A, затем - вокруг оси Y на угол B, и наконец - вокруг оси Z на угол C. Кватернион, задающий вращение, эквивалентное всем трём поворотам, можно вычислить так:
qx.x=sin(A/2)
qx.y=0
qx.z=0
qx.w=cos(A/2)

qy.x=0
qy.y=sin(B/2)
qy.z=0
qy.w=cos(B/2)

qz.x=0
qz.y=0
qz.z=sin(C/2)
qz.w=cos(C/2)

q=qx*qy*qz

ну, о перемножении кватернионов я уже говорил. Кстати, в DirectX (точнее, в D3dx9.lib) есть специальная функция для умножения кватернионов - D3DXQuaternionMultiply, хотя она работает не слишком быстро. Бесконечные преобразования поворотов (кватерниона в матрицу, углов Эйлера - в кватернион и др.) очень ресурсоёмки, т.к. используют тригонометрические функции и требуют кучи умножений. Поэтому в высокоскоростных 3D-приложениях (играх, например) все повороты нужно хранить единообразно - чтобы обходиться без преобразований.
Где можно подробнее почитать о кватернионах? Ну, например, на Gamedev'е:Статьи излагают самые основы кватернионной математики, т.е. на самом деле у кватернионов куда больше возможностей.

Отредактировано Алексей, 27.11.2006 в 12:58.
Старый 27.11.2006, 12:24
NETRAT

offline
Опыт: 83,712
Активность:
Тему в трактир переношу ...

NETRAT добавил:
Да, я повороты матрицами делал(просто не знал для чего кватернионы, благодаря тебе, знаю). Углы Эйлера, имхо - геморрой
Старый 27.11.2006, 12:48
inquiro

offline
Опыт: 721
Активность:
ВАХ!... Сейчас у меня голова взорвется!
Давно я не брал в руки счеты...

Цитата:
Сообщение от Алексей
И как этот вопрос относится к Warcraft'у?

А вращение объектов (костей к примеру) разве не кватерионом задается?
Если задавать поворот в mdl мощнейшим инструментом программирования 3D графики - блокнотом, то без этого не обойтись.

Цитата:
Сообщение от NETRAT
Тему в трактир переношу ...

Потому, что без стакана не разберешься?...

СПАСИБО, Алексей!!!
Старый 27.11.2006, 19:41
Q

offline
Опыт: 360,164
Активность:
inquiro вообще Алексей написал как раз MDLVis
Старый 27.11.2006, 19:51
inquiro

offline
Опыт: 721
Активность:
Я знаю!
СПАСИБО ему еще много раз!
Я бы за это Алексея на руках поносил бы, но не знаю, где его взять...

Отредактировано Q, 28.11.2006 в 23:28.
Старый 27.11.2006, 20:33
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 17:40.