Maneira eficiente de calcular uma matriz de rotação 3x3 a partir da rotação definida por dois vetores 3D

Embora eu tenha encontrado duas soluções para isso, fiquei curioso para saber se existe um método conhecido para executar essa operação, pois parece uma tarefa bastante comum.

Aqui estão os 2 métodos óbvios do psudo-código ...

Ângulo do eixo

Isso é bastante lógico, mas chamasin duas vezes ecos uma vez (no cálculo do ângulo e na conversão do ângulo do eixo para a 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: A função mais direta é bastante lenta, no entanto, como foi apontado nas respostas aqui: é possível evitar o cálculo do ângulo obtendo-seangle_sin eangle_cos, a partir do comprimento do eixo ev1,v2 produto pontual, respectivamente.

Diferença entre duas matrizes

Aqui está outro método que encontrei que constrói duas matrizes 3x3 a partir dos vetores e retorna a diferença.

No entanto, isso é mais lento que o cálculo de eixo / ângulo, que pode ser otimizado (mencionado acima).

Nota. isso assume que os dois vetores estão normalizados, a matriz é a coluna principal (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;
}

Existem maneiras melhores de realizar esse cálculo?

Editar: O objetivo desta pergunta NÃO é otimizar e comparar cada método. Em vez disso, fiquei curioso para saber se existe algum método totalmente diferente e superior que eu não conhecia.

Nota: De propósito, deixei de fora as verificações do caso degenerado para vetores co-lineares (onde o eixo tem comprimento zero), para manter os exemplos simples.

questionAnswers(2)

yourAnswerToTheQuestion