Manera eficiente de calcular una matriz de rotación 3x3 a partir de la rotación definida por dos vectores 3D
Si bien encontré 2 soluciones para esto, tenía curiosidad por saber si hay un método bien conocido para realizar esta operación, ya que parece una tarea bastante común.
Aquí están los 2 métodos obvios de psudocódigo ...
Ángulo del ejeEsto es bastante lógico, pero llamasin
dos veces ycos
una vez (en el cálculo del ángulo y la conversión del ángulo del eje a la matriz).
Matrix3x3 rotation_between_vectors_to_matrix(const Vector v1, const Vector v2)
{
angle = v1.angle(v2);
axis = v1.cross(v2);
/* maths for this is well known */
Matrix3x3 matrix = axis_angle_to_matrix(axis, angle);
return matrix;
}
Editar: La función más directa es bastante lenta, sin embargo, como se ha señalado en las respuestas aquí: se puede evitar calcular el ángulo obteniendoangle_sin
yangle_cos
, desde la longitud del eje yv1,v2
producto de punto respectivamente.
Aquí hay otro método que encontré que construye dos matrices 3x3 a partir de los vectores y devuelve la diferencia.
Sin embargo, esto es más lento que el cálculo del eje / ángulo que se puede optimizar (mencionado anteriormente).
Nota. esto supone que ambos vectores están normalizados, la matriz es la columna mayor (OpenGL).
Matrix3x3 rotation_between_vectors_to_matrix(const Vector v1, const Vector v2)
{
Matrix3x3 m1, m2;
axis = v1.cross(v2);
axis.normalize();
/* construct 2 matrices */
m1[0] = v1;
m2[0] = v2;
m1[1] = axis;
m2[1] = axis;
m1[2] = m1[1].cross(m1[0]);
m2[2] = m2[1].cross(m2[0]);
/* calculate the difference between m1 and m2 */
m1.transpose();
Matrix3x3 matrix = m2 * m1;
return matrix;
}
¿Hay mejores formas de realizar este cálculo?
Editar: El propósito de esta pregunta NO es micro-optimizar y comparar cada método. En cambio, tenía curiosidad por saber si hay algún método totalmente diferente y superior que no conocía.
Nota: Dejé deliberadamente verificaciones para el caso degenerado de vectores co-lineales (donde el eje es de longitud cero), para mantener los ejemplos simples.