Объединить векторы вращения оси - PullRequest
8 голосов
/ 30 ноября 2010

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

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

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

Ответы [ 3 ]

2 голосов
/ 21 октября 2013

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

Построить матрицу кросс-произведения (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

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

2 голосов
/ 01 декабря 2010

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

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

θ (t) = θ 0 + α (tt 0 ) мод 2π

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

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

1 голос
/ 01 декабря 2010

Вы должны использовать единичные кватернионы, а не масштабированные векторы для представления ваших вращений. Может быть показано (не мной), что любое представление вращений, использующее три параметра, столкнется с проблемами (то есть будет единичным) в какой-то момент. В вашем случае это происходит, когда ваш вектор имеет длину 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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...