Структура публикации
- Получение кватерниона из вектора и величины угла разворота
- Обратный кватернион
- Умножение кватернионов
- Поворот вектора
- Рысканье, тангаж, крен
- Серия поворотов
Получение кватерниона из вектора и величины угла разворота
Ещё раз – что такое кватернион? Для разработчика – это прежде всего инструмент, описывающий действие – поворот вокруг оси на заданный угол:
где v – ось, выраженная вектором;
w – компонента, описывающая поворот (косинус половины угла).
Положительное значение угла разворота означает поворот вдоль вектора по часовой стрелке, если смотреть с конца вектора в его начало.
Например, кватернион поворота вдоль оси Х на 90 градусов имеет следующие значения своих компонент: w = 0,7071; x = 0,7071; y = 0; z = 0. Левая или правая система координат, разницы нет – главное, чтобы все операции выполнялись в одинаковых системах координат, или все в левых или все в правых.
С помощью следующего кода (под рукой был Visual Basic), мы можем получить кватернион из вектора и угла разворота вокруг него:
В коде rotate_vector – это вектор, описывающий ось разворота, а rotate_angle – это угол разворота в радианах. Вектор должен быть нормализован. То есть его длина должа быть равна 1.
Не забывайте про ситуацию, когда длина может быть 0. Вместо ошибки вам может понадобиться обработать эту ситуацию индивидуально.
Обратный кватернион
Для поворота вектора кватернионом требуется уметь делать обратный разворот и правильно выполнять операцию умножения кватернионов. Под обратным разворотом я имею ввиду обратный кватернион, т. е. тот, который вращает в обратную сторону.
Чтобы получить обратный кватернион от заданного, достаточно развернуть вектор оси в другую сторону и при необходимости нормализовать кватернион. Нормализация кватерниона так же как и в векторах, это просто приведение к длине = 1.
Например, если разворот вокруг оси Y на 90 градусов = (w=0,707; x = 0; y = 0,707; z=0), то обратный = (w=0,707; x = 0; y = -0,707; z=0). Казалось бы, можно инвертировать только компоненту W, но при поворотах на 180 градусов она = 0. Кватернион, который означает «нет разворота» = (w=1; x = 0; y = 0; z=0), то есть у него длина вектора оси = 0.
Умножение кватернионов
Умножение кватернионов крайне полезная штука. Результатом умножения является кватернион, который после поворота даёт такой же результат, если последовательно выполнить развороты умножаемыми кватернионами. Причём разворот будет происходить в локальной для поворачиваемого вектора системе отчёта, т. е. система отчёта поворачиваемого вектора также двигается.
Умножение кватернионов выполняется следующим образом:
Для того, чтобы умножить кватернион на 3D вектор, нужно вектор преобразовать в кватернион присвоив компоненте W = 0 и умножить кватернион на кватернион. Или подставить ноль и выразить это в виде функции:
Поворот вектора
Теперь, собственно, поворот вектора кватернионом:
Вектор описывающий ось (x=1; y=0; z=1). Угол поворота 180 градусов.
Поворачиваемый вектор (x=0; y=0; z=1). Результат равен (x=1; y=0; z=0).
Рысканье, тангаж, крен
Рассмотрим инструмент формирования кватерниона с помощью поворотов вокруг одной из осей:
Рысканье = heading = yaw = вокруг оси Z; тангаж = altitude = pitch = вокруг оси Y; крен = bank = roll = вокруг оси X.
И в обратную сторону, из кватерниона:
Формулы преобразования зависят от принятой системы координат.
Серия поворотов
Рассмотрим пример:
1. Первый поворот – рысканье (вокруг Z) 90 градусов по часовой;
2. Второй поворот – тангаж (вокруг Y) 90 градусов по часовой;
3. Третий поворот – крен (вокруг X) 90 градусов по часовой.
Рисунки, изображающие поворот и подписанные как «global» демонстрируют повороты относительно неподвижных осей XYZ. Такой результат мы получим, если будем использовать кватернионы разворота по отдельности. Четвёртый рисунок демонстрирует, где окажется вектор, если начальные координаты у него были X=1; Y=0; Z=0.
Рисунки, подписанные как «local» демонстрируют вращение осей вместе с самолетом. То есть все вращения происходят относительно пилота, а не относительно неподвижной системы координат. Четвёртый рисунок показывает, где окажется тот же самый вектор (1; 0; 0) в итоге всех трёх поворотов. Такой результат мы получим, перемножив кватернионы разворота и применив полученный кватернион.
Видео:Вращение, углы Эйлера, Кватернионы в UnityСкачать
Понимание кватернионов в Unity
Бикватернион | Аудио статья в Википедии
Возникли трудности с пониманием того, как использовать вращение (представленное в виде кватерниона) в Unity.
Что я хочу сделать, так это отметить вращение объекта в какой-то момент, а затем узнать его новое вращение вскоре после этого и преобразовать это в количество градусов (или радиан) вращения вокруг осей X, Y и Z в мировом пространстве. произошло.
Я уверен, что это достаточно просто .
- Не могли бы вы добавить более прямой вопрос? Вы просите объяснения кватерниона? Или вы просите кого-нибудь написать весь код, который вам нужен, чтобы делать то, что вы хотите делать? Было бы полезно, если бы вы были более конкретными в том, что вы хотите от сообщества. Благодаря!
Вы можете понять разницу между двумя Quaternion используя Quaternion.Inverse и * оператор
Сначала сохраните ротацию в поле
а затем где-нибудь позже, например,
а затем вы получите представление углов оси Эйлера, используя Quaternion.eulerAngles
- Большое спасибо, это именно то, что мне было нужно. Пробовал и работает. Теперь я понимаю, почему кватернионы так полезны — пробовал делать это с углами Эйлера и повсюду сталкивался с блокировкой кардана.
Видео:Поворот объекта через углы Эйлера и кватернионы в Unity 3DСкачать
Вращение и кватернионы. Сборник рецептов.
Давайте коротко определимся с терминологией. Каждый представляет себе, что такое ориентация объекта. Термин «ориентация» подразумевает, что мы находимся в некоторой заданной системе отсчета. Например, фраза «он повернул голову влево» осмыслена только тогда, когда мы представляем, где находится «лево» и где находилась до этого голова. Это важный для понимания момент, ведь если бы это был монстр с головой на животе макушкой вниз то фраза «он повернул голову влево» уже не покажется такой однозначной.
Трансформацию, которая определенным образом вращает из одной ориентации в другую, назовем поворотом. С помощью поворота можно описать и ориентацию объекта, если ввести некую ориентацию по умолчанию как точку отсчета. Например, любой объект, описанный с помощью набора треугольников, уже имеет ориентацию по умолчанию. Координаты его вершин описываются в локальной системе координат этого объекта. Произвольную ориентацию этого объекта можно описать матрицей поворота относительно его локальной системы координат. Также можно выделить такое понятие как «вращение». Под вращением будем понимать изменение ориентации объекта заданным образом во времени. Чтобы однозначно задать вращение, надо, чтобы в любой момент времени мы могли определить точную ориентацию вращаемого объекта. Другими словами вращение задает «путь», пройденный объектом при изменении ориентации. В такой терминологии поворот не задает однозначного вращения объекта. Важно понимать что, к примеру, матрица не задает однозначного вращения тела, одну и ту же матрицу поворота можно получить, повернув объект на 180 градусов вокруг фиксированной оси и на 180 + 360 или 180 — 360. Эти термины я применяю для демонстрации различий в понятиях, и ни в коей мере не настаиваю на использовании. В дальнейшем оставлю за собой право говорить «матрицы вращения».
При слове ориентация часто возникают ассоциация с направлением. Часто можно услышать фразы подобные «он повернул голову в сторону приближающегося локомотива». Например, ориентацию автомобиля можно было бы описать направлением, в котором смотрят его фары. Однако направление задается двумя параметрами (например, как в сферической системе координат), а объекты в трехмерном пространстве имеют три степени свободы (вращения). В случае с автомобилем он может смотреть в одном направлении как стоя на колесах, так и лежа на боку или на крыше. Ориентацию действительно можно задать направлением, но их потребуется два. Давайте рассмотрим ориентацию на простом примере головы человека.
Договоримся про исходное положение, в котором голова ориентирована по умолчанию (без вращения). За исходное примем положение, в котором голова смотрит лицом по направлению оси «z», а вверх (макушкой) смотрит по направлению оси «y». Назовем направление, в котором повернуто лицо «dir» (без вращения совпадает с «z»), а направление, куда смотрит макушка «up» (без вращения совпадает с «y»). Теперь у нас есть точка отсчета, есть локальная координатная система головы «dir», «up» и глобальная с осями x, y, z. Произвольно повернем голову и отметим, куда смотрит лицо. Глядя в этом же направлении можно вращать голову вокруг оси, совпадающей с направлением взгляда «dir». Например, наклонив голову на бок (прижавшись щекой к плечу) мы будем смотреть в том же направлении, но ориентация головы поменяется. Чтобы зафиксировать поворот вокруг направления взгляда, используем еще и направление «up» (направленно к макушке). В этом случае мы однозначно описали ориентацию головы и не сможем ее повернуть, не изменив направления осей «dir» и «up».
Мы рассмотрели достаточно естественный и простой способ задания ориентации с помощью двух направлений. Как же описать наши направления в программе, чтобы ими было удобно пользоваться? Простой и привычный способ хранить эти направления в виде векторов. Опишем направления с помощью векторов длиной в единицу (единичных векторов) в нашей глобальной системе координат xyz. Первый важный вопрос, как бы наши направления передать в понятном виде графическому API? Графические API работают в основном с матрицами. Нам бы хотелось получить матрицу поворота из имеющихся векторов. Два вектора описывающие направление «dir» и «up» и есть та самая матрица поворота, а точнее два компонента матрицы поворота 3×3. Третий компонент матрицы мы можем получить из векторного произведения векторов «dir» и «up» (назовем его «side»). В примере с головой вектор «side» будет смотреть в направлении одного из ушей. Матрица поворота это и есть координаты трех векторов «dir», «up» и «side» после поворота. Эти вектора до поворота совпадали с осями глобальной системы координат xyz. Именно в виде матрицы поворота очень часто и хранят ориентацию объектов (иногда матрицу хранят в виде трех векторов). Матрицей можно задать ориентацию (если известна ориентация по умолчанию) и поворот.
Похожий способ представления ориентации, называется углы Эйлера (Euler Angles), с тем лишь отличием, что направление «dir» задается в сферических координатах, а «up» описывается одним углом поворота вокруг «dir». В итоге получим три угла вращения вокруг взаимно перпендикулярных осей. В аэродинамике их называют Крен, Тангаж, Рысканье (Roll, Pitch, Yaw или Bank, Heading, Attitude). Крен (Roll) — это наклон головы вправо или влево (к плечам), поворот вокруг оси проходящей через нос и затылок. Тангаж (Pitch) — это наклон головы вверх и вниз, вокруг оси проходящей через уши. И Рысканье (Yaw) — это повороты головы вокруг шеи. Надо помнить, что повороты в трехмерном пространстве не коммутативны, а значит, на результат влияет порядок поворотов. Если мы повернем на R1 а потом на R2, ориентация объекта не обязательно совпадет с ориентацией при повороте на R2 и затем на R1. Именно поэтому при использовании Углов Эйлера важен порядок поворотов вокруг осей. Обратите внимание, что математика углов Эйлера зависит от выбранных осей (мы использовали только один из возможных вариантов), от порядка поворота вокруг них, а также от того в какой системе координат совершаются повороты, в мировой или локальной объекта. В углах Эйлера можно хранить и вращение и поворот.
Огромный недостаток такого представления, отсутствие операции комбинации поворота. Не пытайтесь складывать покомпонентно углы Эйлера. Итоговый поворот не будет комбинацией исходных поворотов. Это одна из самых распространенных ошибок начинающих разработчиков. Чтобы повернуть объект, храня вращение в углах Эйлера, нам придется перевести вращение в другую форму, например в матрицу. Затем перемножить матрицы двух поворотов и из итоговой матрицы извлечь углы Эйлера. Проблема усложняется еще и тем что в частных случаях прямое сложение углов Эйлера работает. В случае комбинации вращений вокруг одной и той же оси, этот метод математически верен. Повернув на 30 градусов вокруг оси X, а затем еще раз вокруг X на 40 градусов мы получим поворот вокруг X на 70 градусов. В случае вращений по двум осям простое сложение углов может давать некий «ожидаемый» результат. Но как только появляется поворот по третьей оси, ориентация начинает вести себя непредсказуемо. Многие разработчики тратят месяцы труда чтобы заставить работать камеру «правильно». Рекомендую обратить пристальное внимание к этому недостатку, особенно если вы уже решили использовать углы Эйлера для представления вращений. Начинающим программистам кажется что, использовать углы Эйлера проще всего. Позволю себе высказать личное мнение, что математика углов Эйлера намного сложнее и коварнее чем математика кватернионов.
Углы Эйлера это комбинация (композиция) вращений вокруг базовых осей. Существует еще один, простой, способ задания вращения. Этот способ можно назвать «смесь» вращений вокруг базовых координатных осей, или просто вращение вокруг произвольной фиксированной оси. Три компоненты описывающие вращение образуют вектор, лежащий на оси, вокруг которой и поворачивается объект. Обычно хранят ось вращения в виде единичного вектора и угол поворота вокруг этой оси в радианах или градусах (Axis Angle). Выбрав подходящую ось и угол можно задать любую ориентацию объекта. В некоторых случаях удобно хранить угол вращения и ось в одном векторе. Направление вектора в этом случае совпадает с направлением оси вращения, а длина его равна углу поворота. В физике, таким образом, хранят угловую скорость. Вектор, совпадающий направлением с осью вращения и длиной представляющей скорость в радианах в секунду.
Видео:ВСЕ про Quaternions в Unity - вращение объектовСкачать
Кватернион
После краткого обзора о представлениях ориентации можно перейти к знакомству с кватернионом.
Кватернион — это четверка чисел, которые ввел в обращение (как считают историки) Уильям Гамильтон в виде гиперкомплексного числа. В этой статье я предлагаю рассматривать кватернион как четыре действительных числа, например как 4d вектор или 3d вектор и скаляр.
Существуют и другие представления кватерниона, которые я не буду рассматривать.
Как же хранят вращение в кватернионе? Практически также как и в «Axis Angle» представлении, первые три компонента представляют вектор, лежащий на оси вращения, причем длина вектора зависит от угла поворота. Четвертый компонент зависит только от величины угла поворота. Зависимость довольно простая — если взять единичный вектор V за ось вращения и угол alpha за вращение вокруг этой оси, тогда кватернион представляющий это вращение
можно записать как:
Для понимания того, как хранит вращение кватернион, вспомним про двумерные вращения. Вращение в плоскости можно задать матрицей 2×2, в которой будут записаны косинусы и синусы угла поворота. Можно представить, что кватернион хранит комбинацию оси вращения и матрицы половины поворота вокруг этой оси.
💥 Видео
Векторы и Манипуляции с ними, Vector3 - Unity урокиСкачать
17. Введение в кватернионыСкачать
Unity 3D \ C# \ Анимация вращения \ Кватернионы (Объяснение)Скачать
A.7.28 Описание поворотов кватернионамиСкачать
Кватернионы | Вращение в 3D [Самая суть]Скачать
Unity C#. Quaternion LookRotation. Справочник. Мусин Михаил.Скачать
ВРАЩЕНИЕ В КООРДИНАТАХ. КВАТЕРНИОНЫ И УГЛЫ ЭЙЛЕРА - С++ OpenGL ЧАСТЬ #3Скачать
Unity C#. Transform EulerAngles. Справочник. Мусин Михаил.Скачать
#225. КВАТЕРНИОНЫ и углы ЭйлераСкачать
Урок Houdini "Кватернионы для чайников" (RUS)Скачать
Кватернионы и октавы. 3. Повороты в пространстве. Углы Эйлера: крен, тангаж, рыскание.Скачать
Unity C#. Transform RotateAround. Справочник. Мусин Михаил.Скачать
Плавный поворот к цели в Unity и вращение до указанного угла / Как создать игру [Урок 128]Скачать
Unity Как узнать угол между двумя объектамиСкачать
Unity 18 C# Урок 5 - Векторы и Манипуляции с ними, Vector3Скачать
А.7.19 Поворот в трехмерном пространствеСкачать
Unity. Скрипт. Вращение объекта.Скачать