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

Справочная информация:

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

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

  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, математика.stackexchange и все остальное, что Google предоставил и прочитал следующие ресурсы до сих пор в надежде выяснить ответ самостоятельно:

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

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

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

2 ответов


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

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 и здесь (последняя ссылка также указывает на бумагу).


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

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

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

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