Объединить векторы оси вращения

Я экспериментирую с использованием векторов оси-угла для поворотов в своем игровом движке для хобби. Это трехкомпонентный вектор вдоль оси вращения с длиной поворота в радианах. Мне они нравятся, потому что:

  • В отличие от quats или матриц вращения, я действительно могу видеть числа и визуализировать вращение в уме.
  • Они занимают немного меньше памяти, чем кватернионы или матрицы.
  • Я могу представлять значения за пределами диапазона от -Pi до Pi (это важно, если я сохраняю угловую скорость)

Однако у меня есть жесткий цикл, который обновляет вращение всех моих объектов (десятки тысяч) в зависимости от их угловой скорости. В настоящее время единственный известный мне способ объединить два вектора оси вращения — преобразовать их в кватернионы, умножить их, а затем преобразовать результат обратно в ось/угол. С помощью профилирования я определил это как узкое место. Кто-нибудь знает более простой подход?


person EricP    schedule 30.11.2010    source источник
comment
Означает ли это, что 3 значения представляют последовательные повороты вокруг 3 ортогональных осей? По сути, углы Эйлера такие, что [phi,psi,theta] может представлять RX(phi)*RY(psi)*RZ(theta). Если это так, вам нужно найти способ построить матрицу вращения 3x3 и извлечь из нее ось-угол.   -  person John Alexiou    schedule 01.12.2010
comment
Нет, я не использую углы Эйлера. Это угол оси, где длина вектора является углом.   -  person EricP    schedule 01.12.2010


Ответы (3)


Ваше представление эквивалентно вращению кватернионов, при условии, что ваши векторы вращения имеют единичную длину. Если вы не хотите использовать какую-либо стандартную структуру данных кватерниона, вы должны просто убедиться, что ваши векторы вращения имеют единичную длину, а затем разработать эквивалентную умножение кватернионов / обратное вычисление для определения совокупного вращения. Возможно, вы сможете уменьшить количество умножений или сложений.

Если изменяется только ваш угол (т. е. ось вращения постоянна), то вы можете просто использовать линейное масштабирование угла и, если хотите, модифицировать его так, чтобы он находился в диапазоне [0, 2). Итак, если у вас есть скорость вращения рейданов в секунду, начиная с начального угла 0 в момент времени t0, то конечный угол поворота в момент времени t определяется выражением :

(t) = 0+(t-t0) по модулю 2

Затем вы просто применяете это вращение к своей коллекции векторов.

Если ничто из этого не улучшит вашу производительность, вам следует подумать об использовании библиотеки готовых кватернионов, поскольку такие вещи уже оптимизированы для типов приложений, которые вы обсуждаете.

person andand    schedule 30.11.2010
comment
1. Мои векторы не имеют единичной длины. Их длина равна углу поворота в радианах. 2. Я использую структуру данных кватерниона. 3. Во многих случаях меняется не только мой ракурс, но это было бы хорошей проверкой оптимизации. - person EricP; 01.12.2010
comment
выработать эквивалентное умножение кватерниона / обратное вычисление для определения совокупного вращения. Это то же самое, что преобразование из угла оси в кватернион и обратно? Моя текущая реализация взята из FAQ по Matrix и Quaternion (j3d.org/matrix_faq/matrfaq_latest.html) - person EricP; 01.12.2010

Вы можете сохранить их как значения угловой оси.

Постройте матрицу перекрестного произведения (anti-symmetric), используя значения угловой оси (x,y,z), и взвесьте элементы этой матрицы, умножив их на значение угла. Теперь просуммируйте все эти матрицы перекрестных произведений (one for each angle axis value) и найдите окончательную матрицу вращения, используя экспоненциальную матрицу.

Если матрица A представляет эту матрицу перекрестного произведения (построенную из значения оси угла), то

exp(A) эквивалентна матрице поворота R (i.e., equivalent to your quaternion in matrix form).

Следовательно,

exp (A1 + A2) = R1 * R2

вероятно, более дорогой расчет в конце концов ...

person Michael    schedule 21.10.2013

Вы должны использовать единичные кватернионы, а не масштабированные векторы для представления ваших вращений. Можно показать (не мной), что любое представление вращений с использованием трех параметров в какой-то момент столкнется с проблемами (т.е. будет сингулярным). В вашем случае это происходит, когда ваш вектор имеет длину 0 (т.е. идентичность) и длину 2pi, 4pi и т. д. В этих случаях представление становится сингулярным. Единичные кватернионы и матрицы вращения не имеют этой проблемы.

Судя по вашему описанию, вы обновляете состояние вращения в результате численного интегрирования. В этом случае вы можете обновить состояние вращения, преобразовав скорость вращения (\omega) в скорость кватерниона (q_dot). Если мы представим ваш кватернион как q = [q0 q1 q2 q3], где q0 — скалярная часть, тогда:

q_dot = E*\omega

где

    [ -q1 -q2 -q3 ]
E = [  q0 -q3  q2 ]
    [  q3  q0 -q1 ]
    [ -q2  q1  q0 ]

Тогда ваше обновление становится

q(k+1) = q(k) + q_dot*dt

для простой интеграции. При желании вы можете выбрать другого интегратора.

person Commodore63    schedule 01.12.2010
comment
Что означает, что вращение станет сингулярным, и какие проблемы это принесет? - person EricP; 01.12.2010
comment
Это может или не может вызвать проблему. Это означает, что в этих местах вы фактически теряете степень свободы. Это, в свою очередь, означает, что если вы хотите преобразовать скорости между вашим представлением и другим (скажем, кватернионами), матрица преобразования (т.е. якобиан) является сингулярной (не может быть инвертирована). - person Commodore63; 02.12.2010
comment
Почему это проблема, если вращение идентичности теряет степень свободы, поскольку оно все равно ничего не вращает? - person whoKnows; 05.04.2020