Сохраняйте относительное положение, используя кватернионную ориентацию

Допустим, у меня есть объект (A) с позицией, хранящейся в виде трехзначного вектора, и ориентацией, хранящейся в виде кватерниона.

У меня есть второй объект (B) с той же информацией.

Объект B по какой-то причине внезапно приварился к объекту A. Теперь он застрял и должен идеально перемещаться относительно объекта A.

Если объект B приклеен к углу объекта A, а объект A вращается, объект B должен находиться в том же относительном положении и ориентации в том же углу, что и раньше.

Чтобы проиллюстрировать то, что я прошу, это должно выглядеть примерно так:

Изображение

До сих пор мне удавалось взять положение объекта B и преобразовать его с помощью обратной позиции/ориентации объекта A, сохранив точное относительное положение, а затем, когда объект A вращается, я просто преобразую относительное положение по положению/ориентации объекта A, и телепортируйте объект B в это место. Это удерживает объект B в углу A, как и ожидалось... однако это не поворачивает объект B, чтобы он соответствовал объекту A... как мне отслеживать относительную ориентацию, используя кватернионы или матрицы (углы Эйлера - это только наихудший сценарий, так как их вычисление дорого).

РЕДАКТИРОВАТЬ: У меня есть только кватернион до и кватернион после. Подробностей о самой ротации нет.

Кроме того, вращение произвольное и свободное, оно могло быть вокруг любой оси или сразу по нескольким осям.


person mcmonkey4eva    schedule 21.05.2015    source источник


Ответы (2)


Самый идеальный ответ пришел ко мне после долгих гуглений и экспериментов: не обращайте внимания на оригинальные идеи, приобретайте матрицы!

B.Matrix * Invert(A.Matrix) хранится как маркер relative, а затем для восстановления просто замените матрицу B на relative * A.MATRIX.

Это идеально регулирует как вращение, так и положение одним всемогущим махом.

Я понятия не имею, как сделать то же самое с кватернионами, но какая разница, когда у нас есть матрицы!

person mcmonkey4eva    schedule 22.05.2015
comment
Я как раз собирался ответить на это! И вы полностью на правильном пути. Забудьте об углах или положениях кватернионов. Сначала разберитесь с матрицами и линейными преобразованиями. Думайте о матрице как о пространстве — в математике это называется основанием. Преобразование вектора путем его умножения на матрицу переводит его в это пространство. И отсюда вытекает самая неинтуитивная вещь о матрицах: перейти в пространство A и оттуда в B — это не то же самое, что перейти в B, а затем в A. - person starmole; 22.05.2015
comment
@starmole: неверно говорить, что основа (не база) — это то же самое, что и пробел. Основа — это то, что порождает или охватывает пространство, но для одного и того же пространства может быть много разных основ. В ситуации, о которой мы здесь говорим, пространство всегда равно R^3, а вращение/перемещение — это просто изменение системы координат, а не пространства. - person cfh; 22.05.2015
comment
Чтобы объяснить, почему это решение работает: инвертирование A.Matrix в основном преобразует B в локальную систему координат A. Как только это будет сделано, мы можем просто преобразовать B вместе с остальной частью A, применив A.Matrix. - person cfh; 22.05.2015
comment
Или в математических терминах: relative * A.Matrix = B.Matrix * inv(A.Matrix) * A.Matrix = B.Matrix, поэтому B сохраняет свое исходное положение и преобразование в мировых координатах, но выражается в системе координат A. - person cfh; 22.05.2015
comment
@cfh ты прав конечно. английский не является моим родным языком, что немного усложняет математические термины (база или основа?). Но я также не пытался быть точным, но полезным. Я думал, что слово «пространство» описывает то, как могут думать люди, занимающиеся 3D-графикой, но, возможно, это было неправильно, потому что это неправильный термин в математике. - person starmole; 22.05.2015

Вы хотите реализовать алгоритм, описанный здесь.

Вам нужно повернуть B вокруг произвольной оси — той же оси, вокруг которой вы вращаете A. Я предполагаю, что у вас есть ось, вокруг которой вы вращаете A. Если нет, вы можете вычислить его, используя центральную точку A и линию, параллельную нормали вращения.

person kaz    schedule 22.05.2015
comment
Он не вращается вокруг оси, он вращается свободно. Единственная информация, которая у меня есть, это до-кватернион и после-кватернион. - person mcmonkey4eva; 22.05.2015
comment
Он вращается вокруг некоторой оси, даже если она проходит через A. У каждого вращения есть ось. - person kaz; 22.05.2015
comment
Однако он мог вращаться вокруг нескольких осей одновременно. - person mcmonkey4eva; 22.05.2015
comment
Истинный. Затем вам нужно будет применить эти повороты как отдельные операции. Просто для ясности: когда я говорю «ось», я не имею в виду оси X, Y, Z — я имею в виду линию, которая является осью вращения. - person kaz; 22.05.2015
comment
Хотя я не могу этого сделать. Я не контролирую систему, которая вращает вещи, мне просто дается положение/ориентация объекта в любой момент времени, и мне нужно точно удерживать объект. (Для ясности: я привязываю нефизический объект к физическому объекту в физическом движке. Физический движок не обеспечивает «событие вращения» или что-то еще, я просто должен реагировать на каждый шаг обновления) - person mcmonkey4eva; 22.05.2015
comment
Вы можете рассчитать поворот между положением А и ориентацией до и после. Затем примените тот же поворот к B (но используйте ту же ось). - person kaz; 22.05.2015
comment
Хорошо, звучит разумно... как бы я это сделал? В отличие от углов Эйлера, я не могу просто вычесть один кватернион из другого или что-то в этом роде. - person mcmonkey4eva; 22.05.2015
comment
@mcmonkey4eva: Каждое вращение можно записать как вращение вокруг одной оси. Если вы объедините несколько вращений, конечным результатом снова будет вращение (но с другой осью). - person cfh; 22.05.2015