Pull to refresh

Comments 48

Если кому интересно, то вот тут есть небольшой FAQ по кватернионам и матрицам — умножение, конвертация в/из угла вращения и оси, Эйлеровы углы вращения.
Почему вы так настаиваете на том, что я пользуюсь углами Эйлера?
Мне кажется что квантерион это матрица 4х4! И с ними можно разобраться (узнать что у них внутри и как действует).
Не совсем так. Сам по себе кватернион — это четыре числа. А вот эти четыре числа уже можно легко конвертировать в матрицу 3х3 или 4х4.
Если говорить простым языком: кватернион — это положение объекта в пространстве относительно некой системы координат; а углы Эйлера — это на какие углы вокруг каких осей надо повернуть объект, чтобы он принял желаемое положение.
Не видел ни одного тридэшного приложения, где можно было бы вводить вращения кватернионами или даже матрицами. Везде конечное представление выводится с помощью эйлеров. Так что в некотором роде все пользуются именно ими.
Да, начать разбираться можно, но сложно будет остановиться. Сначала сложение и умножение, потом логарифмы, потом кватернионные группы… Лучше просто пользоваться как есть :)
Урок 5. «Матрицы». — 77 страница (по 86-ую, немного).

Станислав Горнаков. «DirectX 9. Уроки программирования на C++». СПб.: БХВ 2005. — 400;
Не самый авторитетный для меня источник. Но моя первая книга о 3D программировании.

Книга о DirectX и как им пользоваться. Сразу в матрицы, о квантерионах и речи нет. Углы Эйлера не упомянуты.
Их (углы Эйлера) может быть интуитивно хочется использовать после школьной геометрии, но их возможности так же «школьны».
Матрицы — одно и тоже что квантерион, если не более гибкий инструмент. Ими пользуются для анимирования объектов в 3D пространстве.
Квантерион — это более научный, из мира физики термин.
Матрицы — одно и тоже что квантерион

Бред. Матрицы — вращение представленное углами эйлера. Ничего общего с кватернионами не имеет, разве что кватернион можно представить в виде матрицы вращения, которое по сути будет той же матрицей вращения со всеми вытекающими недостатками.

А какая связь между матрицами и углами Эйлера? Матрица — координаты векторов, в которые переходят базисные векторы при данном вращении. Да, её можно разложить в произведение трёх матриц поворотов вокруг некоторых координатных осей (и тогда получатся углы Эйлера), но ведь можно этого и не делать — оставить матрицу девятью числами.
Да, вы правы, точнее сказать: матрица поворота описывает вращение вокруг произвольного вектора.
Не совсем так. Матрица поворота описывает вообще произвольное вращение, которое, в случае трёхмерного пространства случайно оказывается вращением вокруг какого-то вектора (а в случае четырёхмерного, например, уже не обязательно). И извлечь этот вектор из матрицы не очень просто. Вот кватернион — гораздо лучше: в нём и вектор, и угол записаны почти в явном виде.
Не видел ни одного тридэшного приложения, где можно было бы вводить вращения кватернионами или даже матрицами. Везде конечное представление выводится с помощью эйлеров. Так что в некотором роде все пользуются именно ими.


Отчасти. В 3ds max и все внутренние представление вращения — только через кватернионы. В блендере и Maya думаю то же. Ибо без этого никуда, Гимбал лок — это большая проблема и игнорить её нельзя. В частности для анимации все используют кватернионы сейчас.

А для юзера обычно дается упрощение в виде углов Эйлера, которое на самом деле добавляет вращение кватерниону внутри. Или делают отдельно два способа задания вращения. В Майе вроде так.
Все-таки, несовсем понятно, почему кватернионы лучше, чем углы Эйлера или матрицы поворотов. И всегда ли они лучше, кстати?
Кватернионы лучше, потому что их умножение непрерывно: если мы повернём кватернион на малый угол, то его коэффициенты изменятся незначительно. Далее, их применение, в отличие от углов Эйлера, не требует тригонометрии — достаточно умножения. Можно легко найти кватернион перехода из одного положения в другое (поделив кватернионы друг на друга). И рассчитать наиболее плавную траекторию поворота. С углами Эйлера всё это проделать заметно сложнее.
А углы Эйлера лучше тем, что они нагляднее. Проще задать координаты «из головы». И проще понять смысл преобразования, если оно задано углами Эйлера. Компьютеру же кватернионы удобнее. Хотя от матриц он тоже не откажется :)
Спасибо, это уже понятнее! Но разве чтобы найти коэффициенты кватерниона не потребуется брать косинусы и синусы от угла поворота?
Это придётся сделать один раз. И только для одного угла (точнее, даже, от его половинки :D ) — при генерации этого кватерниона. Для поворотов на малый угол тригонометрия уже не нужна, там работают приближения sin(x)=x, cos(x)=1. Потребуется только один квадратный корень.
Ага, понял.
А как кватернионы спасают от gimbal lock?
Тем что вектор умножается на не на матрицу поворота, а на кватернион. И тем что каждая такая трансформация не зависит от предыдущей.
Углы Эйлера для анимации можно вообще не рассматривать, у них есть шарнирный замок, который отсутствует у матриц и кватернионов. Запись кватерниона немного компактнее матрицы, четыре числа против девяти, хотя на нынешнем железе память давно не проблема. Интерполяция кватернионов проще. Рано или поздно накапливаются ошибки вычислений над дробями и нужно от них избавляться, нормализовать кватернион тоже проще, чем ортогонализировать матрицу. Внешний вид кватерниона менее презентабелен чем у углов Эйлера, но это же касается и матриц. Умножение кватернионов быстрее. Матрицы и кватернионы имеют разное строение и разные возможности по оптимизации, иногда матрицы не требуют операций там, где они нужны у кватернионов. Если мне не изменяет память, OpenGL не умеет работать с кватернионами и их нужно конвертировать в матрицу. Короче говоря, если если нужно много-много вращений, то с кватернионами будет меньше проблем, если нужно просто указать ориентацию объекта, то матрицы могут быть быстрее.
Насчёт того, что умножение кватернионов быстрее — не очевидно. Конечно, если брать только повороты, то два кватерниона перемножаются за 16 умножений, а две матрицы за 27. Но если добавить сдвиги? Для матриц потребуется всего 36 умножений. А сколько для пары (кватернион, сдвиг)? На первый взгляд, получается 44. Если быстренько перевести один из кватернионов в матрицу, получится 35, но это не считая умножений на двойки. Или есть способ сделать это быстрее?
Согласен с Mrrl.
Еще, есть такое понятие в анимировании, как «Матрица гомографии». Это неравномерное искажение объекта.
Можно ли такое сделать квантерионами? А перспективное преобразование. Повороты, сдвиги, масштабирование — это только основные возможности матриц.

Так же из собственного опыта могу сказать(если кому интересно), что коэффициенты матрицы 3x3( входящей в состав 4x4 используемой в 3D) — это вектора ортов оX, oY, oZ пространства производимого данной матрицей. И так далее. Зная такие вещи, программирование матрицами не страшно.
С другой стороны, то, что пространство коэффициентов кватернионов всего лишь четырёхмерно, помогает при решении, например, таких задач, как поиск наилучшего совмещения двух и более сцен или поиск перемещения с данными свойствами. Недавно мне понадобилось перебрать все возможные повороты сферы с шагом в несколько градусов. Построить достаточно регулярную решетку на гиперсфере было несложно. Как бы я перебирал ортогональные матрицы — даже боюсь представить :) Наверное, через углы Эйлера…
Интересная тема. Нужно изучить более подробно. Почитаю про квантерионы еще. Уверен в них тоже есть свой наглядный математико-геометрический смысл.
Прежде всего — с их помощью удобно представить себе множество всех поворотов пространства в виде обычного трёхмерного шара. Центр шара — тождественное преобразование, точки границы — повороты на 180 градусов (симметричные точки отождествляются), остальные точки внутри — повороты на разные углы вокруг своих радиус-векторов. Например, множество поворотов, переводящих один вектор в другой, образует кривую, похожую на половинку эллипса, соединяющую две противоположные точки сферы.
Спасибо.
Надо написать конвертор (прямой и обратный если существуют) и тогда думаю все встанет на свои места.
Между кватернионами и матрицами?
Из кватерниона в матрицу сравнительно легко (не так давно где-то тут даже приводился его код). А вот обратно — сложнее, придётся искать собственный вектор матрицы.
Чуть выше приводил ссылку. Вот тут подробно расписана конвертация в обе стороны.
Спасибо за подробный ответ.

Признаюсь, меня больше интересует приложение кватернионов для робототехники, а не для анимации. Я как-то краем уха слышал, что на кватернионах проще считать кинематику, но очень сложно считать динамику, например.
UFO just landed and posted this here
UFO just landed and posted this here
i — это симметрия относительно оси Ox, а j — симметрия относительно Oy. Их суперпозиция будет как раз симметрией относительно Oz, т.е. k:
(x,y,z) -> (x,-y,-z) -> (-x,-y,z).
А вообще, так эти кватернионы определили, иначе у них никак не получалось существования деления.
Любопытно, что для кватернионов существует два деления (a на b): деление левое (b^(-1)*a) и правое (a*b^(-1))
UFO just landed and posted this here
Это и есть мнимые единицы. Любое из множеств кватернионов a+b*i, a+b*j, a+b*k и даже a+b*(i+2*j+2*k)/3 ведёт себя как множество комплексных чисел с вещественной частью a и мнимой частью b. В кватернионах уравнение q^2=-1 имеет в качестве решений всю сферу {i*x+j*y+k*z: x^2+y^2+z^2=1}.
Это либо определение, либо следствие из определения. Что такое кватернион? Это четверка вещественных чисел и правилами умножения и сложения (кольцо). Немного методологии. Для того, чтобы кольцо было полем (расширением поля комплексных чисел, с реализацией операции «взять обратный элемент» и без «делителей нуля») «умножение» определяется немного не так и отсюда вытекает, в том числе, что i*j должно равняться k.
Кватернионы образуют тело в силу некоммутативности умножения.
Странно, что в статье нет самой главной формулы — как кватернион применить к вектору (или я её не увидел). Если у нас есть кватернион q, то его действие на вектор v равно q*v*q^(-1), где v — кватернион с нулевой действительной частью. Или q^(-1)*v*q, в зависимости от нашей интерпретации (что сейчас выбрано в компьютерной графике, к сожалению, не знаю). q^(-1) — кватернион обратный данному, его можно найти по формуле
[w,x,y,z]^(-1)=[w,-x,-y,-z]/(w^2+x^2+y^2+z^2).
А чего про интерполяцию кватернионов не слова, ведь главное для анимации не умножение — сложение а старый добрый slerp.
Вы бы лучше исходники выложили: вот у меня, например, линукс. И я непонятный бинарник запускать не собираюсь. Да и толку от бинарника — 0!
И еще: не факт, что он вообще запустится у меня (если только вы его полностью статическим не сделали).

По поводу кватернионов у меня такой вопрос: натыкались ли вы на приличные свободные библиотеки (GPL3 или хотя бы GPL2), реализующие операции с кватернионами?
А можно пояснить: что это? Скачал исходники и без понятия, что с ними делать: ни Makefile'а, ни autotools, ни cmake…
Что это?

Насчет буста: я только чистыми сями пользуюсь, мне буст не нужен.
Это проект Unity3d, сейчас исправлю описание. Боюсь, что у вас не получится собрать его под линуксом, я записал для вас видео

Добрый день, спасибо за статью.
Я пытаюсь посчитать (кинетическую) энергию вращения rigidbody в Unity3d, нигде прямых указаний на формулы не нашел.
А в формуле с необходимостью употребляется кватернион вращения главных моментов инерции, так что…
Не подскажите ли, верна ли формула, которую я попытался «воссоздать» сам:
Vector3 av = rigidbody.angularVelocity;
Vector3 itr = rigidbody.inertiaTensorRotation;
Vector3 it = rigidbody.inertiaTensor;

float E = Vector3.Dot(av, itr * Vector3.Scale(it, Quaternion.Inverse(itr) * av)) / 2f;


Вы про эту формулу из википедии?
image
Угловая скорость есть, тензор инерции тоже есть. Что такое тензор инерции и зачем нужно его вращение я не знаю, никогда не сталкивался, так что тут я вам не помощник. А зачем вам понадобилась энергия вращения?
Примерно про эту. Если считать, что тензор инерции считается применением к вектору главных моментов инерции кватерниона поворота этого самого вектора, то получается примерно та формула, что я написал.
Вот только нигде в документации в явном виде не написано, как правильно «комбинировать» кватернион поворота и вектор главных моментов. Умножая всё это дважды на вектор скорости. Затруднение.

Что касается энергии вращения, то я с удивлением обнаружил, что в физике Unity энергию столкновения надо считать самому.
Мой способ расчета потери энергии при соударении:
Для этого перед соударением (на последнем физическом апдейте) запомнить угловую и линейную скорость обоих тел, после выхода из рассчитать потерю энергии: кинетическую (линейную + вращения) энергию обоих тел после столкновения вычесть из той же энергии до столкновения. Таким образом можно определить, сколько энергии в системе сталкивающихся тел «потерялось», то есть перешло в деформации, излучение, тепло.
Думаю, вполне очевидно, почему считать изменение энергии только для одного из сталкивающихся тел недостаточно.

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

Кстати, вопрос вдогонку: При событии OnCollisionEnter тела уже столкнулись, их скорости изменены по сравнению с прошлым кадром. Нет ли у Вас соображений по поводу того, как получить скорости rigidbody любого «физического» тела без прикрепления к нему в редакторе или в коде скрипта с отслеживанием скоростей (путем их запоминания в FixedUpdate)?

Спасибо за статью. Может подскажете так же без углубления на основе действий над кватернионами, как вращать объект вокруг точки в пространстве?
И еще, как можно создать поворот на основе расстояния? То есть чтобы объект повернулся вокруг точки не на Х градусов, а прошел вокруг точки Х условных метров. Или же это в любом случае сведется к вычислению угла?
Sign up to leave a comment.

Articles