Объединение кватернионов с разной точкой поворота

История:

В настоящее время я использую шейдер скелетной анимации в GLSL, и для экономии места и сложности я использую Quaternions для вращения костей с использованием взвешенного умножения кватернионов (каждой кости) для накопления "окончательного вращения" для каждой вершины.

Что-то вроде: (псевдокод, просто предположим, что математика кватернионов работает как ожидалось)

  float weights[5];
  int bones[5];
  vec4 position;

  uniform quaternion allBoneRotations[100];
  uniform vec3 allBonePositions[100];

  main(){
  quaternion finalQuaternion;
  for(i=0;i<5;i++){finalQuaternion *= allBoneRotations[bones[i]]*weights[i];}
  gl_position = position.rotateByQuaternion(finalQuaternion);
  }

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

Проблема:

Я был в процессе добавления "опорных точек" / "совлокальных мест" к каждой кости (отрицательный перевод, поворот на "окончательный кватернион", перевод), когда я понял, что "окончательный кватернион" не будет принимать при совпадении самих кватернионов учитываются разные точки поворота. В этом случае каждое вращение кости будет обработано так, как если бы оно было вокруг точки (0,0,0).

Учитывая, что кватернионы представляют только поворот, кажется, мне нужно либо "добавить" позицию к кватернионам (если это возможно), либо просто преобразовать все кватернионы в матрицы, а затем умножить матрицу на объединение ряда переводов и поворотов. Я действительно надеюсь, что последнее не понадобится, поскольку кажется, что это будет действительно неэффективно, сравнительно.

Я искал mathoverflow, math.stackexchange и все, что еще предоставлял Google, и читал следующие ресурсы до сих пор в надежде выяснить сам ответ:

Консенсус в том, что Quaternions не кодируют "перевод" или "позицию" в каком-либо смысле и, похоже, не обеспечивают интуитивно понятный способ имитации, поэтому чистая математика кватернионов вряд ли будет жизнеспособным решением.

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

Или использует кватернионы в этой ситуации только плохую идею на первый взгляд?

Ответ 1

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

x' = R(q)*(x-pivot)+pivot = R(q)*x + (pivot-R(q)*pivot) = R(q)*x+p,

где q - ваш кватернион, R(q) - это матрица вращения, построенная из него, а p=pivot-R(q)*pivot - компонент положения/перевода. Если вы хотите объединить два таких преобразования, вы можете сделать это, не перебирая полноразмерное умножение:

x'' = R(q2)*x'+p2 = R(q2)*R(q)*x + (R(q2)*p+p2) = R(q2*q)*x + (R(q2)*p+p2).

Таким образом, объединенный кватернион будет q2*q, а комбинированное положение - R(q2)*p+p2. Обратите внимание, что вы даже можете применять кватернионы к векторам (R(q2)*p и т.д.) Без явного построения матриц вращения, если вы хотите их полностью избежать.

Тем не менее, существует понятие "двойных кватернионов", которые на самом деле содержат компонент трансляции и, по-видимому, лучше для представления движений винта. Проверьте их в Wiki и здесь (последняя ссылка также указывает на бумагу).

Ответ 2

После обширного дополнительного поиска и чтения больше о кватернионах, чем любой здравомыслящий человек, я, наконец, нашел свой ответ здесь:

http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/other/dualQuaternion/index.htm

Оказывается, Двойные кватернионы действуют аналогично действительным кватернионам, причем многие из математических операций основаны на правильной математике кватернионов, но они обеспечивают как ориентацию, так и смещение, и могут быть объединены для любой требуемой последовательности перевода вращения например, преобразование матрицы преобразования, но без способности сдвига/масштабирования.

На странице также есть раздел, который точно выполняет функцию "поворот вокруг произвольной точки", которую я требую, используя двойное умножение кватернионов. Возможно, мне следовало бы изучить немного больше, прежде чем спрашивать, но, по крайней мере, ответ здесь сейчас, если кто-то еще смотрит.