math - Combinar vectores de rotación del eje
3d matrix (3)
Estoy experimentando con el uso de vectores de ángulo de eje para rotaciones en mi motor de juego de hobby. Este es un vector de 3 componentes a lo largo del eje de rotación con una longitud de la rotación en radianes. Me gustan porque:
- A diferencia de las matrices de quats o rotación, puedo ver los números y visualizar la rotación en mi mente
- Son un poco menos memoria que los cuaterniones o las matrices.
- Puedo representar valores fuera del rango de -Pi a Pi (Esto es importante si guardo una velocidad angular)
Sin embargo, tengo un ciclo cerrado que actualiza la rotación de todos mis objetos (decenas de miles) en función de su velocidad angular. Actualmente, la única forma que conozco de combinar dos vectores de ejes de rotación es convertirlos en cuaterniones, multiplicarlos y luego convertir el resultado a un eje / ángulo. A través del perfil, he identificado esto como un cuello de botella. ¿Alguien sabe un enfoque más directo?
Tu representación es equivalente a la rotación del cuaternión , siempre que tus vectores de rotación sean unidad de longitud. Si no desea utilizar alguna estructura de datos cuaternarios enlatados, simplemente debe asegurarse de que sus vectores de rotación sean de longitud unitaria, y luego calcular las multiplicaciones de cuaterniones equivalentes / cálculos recíprocos para determinar la rotación agregada. Es posible que pueda reducir el número de multiplicaciones o adiciones.
Si su ángulo es lo único que está cambiando (es decir, el eje de rotación es constante), entonces puede simplemente usar una escala lineal del ángulo y, si lo desea, modificarlo para que esté en el rango [0, 2π). Entonces, si tiene una tasa de rotación de α raidans por segundo, comenzando desde un ángulo inicial de θ 0 en el tiempo t 0 , entonces el ángulo de rotación final en el tiempo t viene dado por:
θ (t) = θ 0 + α (tt 0 ) mod 2π
Luego, simplemente aplica esa rotación a tu colección de vectores.
Si nada de esto mejora su rendimiento, debería considerar el uso de una biblioteca cuaternaria enlatada, ya que las cosas ya están optimizadas para los tipos de aplicaciones que está ejecutando.
Debe usar unidades cuaternarias en lugar de vectores escalados para representar sus rotaciones. Puede mostrarse (no yo) que cualquier representación de rotaciones que utilice tres parámetros tendrá problemas (es decir, será singular) en algún momento. En su caso, ocurre cuando su vector tiene una longitud de 0 (es decir, la identidad) y en longitudes de 2pi, 4pi, etc. En estos casos, la representación se vuelve singular. Los cuaterniones unitarios y las matrices de rotación no tienen este problema.
Según su descripción, parece que está actualizando su estado de rotación como resultado de la integración numérica. En este caso, puede actualizar su estado de rotación convirtiendo su tasa de rotación (/ omega) en una tasa de cuaternión (q_dot). Si representamos su cuaternión como q = [q0 q1 q2 q3] donde q0 es la parte escalar, entonces:
q_dot = E*/omega
dónde
[ -q1 -q2 -q3 ]
E = [ q0 -q3 q2 ]
[ q3 q0 -q1 ]
[ -q2 q1 q0 ]
Entonces tu actualización se convierte
q (k + 1) = q (k) + q_dot * dt
para una integración simple. Puede elegir un integrador diferente si lo desea.
Puede mantenerlos como valores de eje angular.
Construya una matriz de producto cruzado (anti-symmetric)
utilizando los valores del eje del ángulo (x,y,z)
y pondere los elementos de esta matriz multiplicándolos por el valor del ángulo. Ahora resuma todas estas matrices de productos cruzados (one for each angle axis value)
y encuentre la matriz de rotación final usando la matriz exponencial.
Si la matriz A representa esta matriz de productos cruzados (construida a partir del valor del eje de ángulo), entonces,
exp(A)
es equivalente a la matriz de rotación R
(ie, equivalent to your quaternion in matrix form)
.
Por lo tanto,
exp (A1 + A2) = R1 * R2
probablemente una calucación más cara al final ...