Эффективный способ вычисления матрицы вращения 3x3 из вращения, заданного двумя трехмерными векторами

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

Вот 2 очевидных метода псудокода ...

Угол оси

Это вполне логично, но звонкиsin дважды иcos один раз (при расчете угла и угла преобразования в матрицу).

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;
}

редактировать: Самая простая функция довольно медленная, однако, как уже указывалось в ответах здесь: вычисление угла можно избежать, если получитьangle_sin а такжеangle_cosот длины оси иv1,v2 скалярное произведение соответственно.

Разница между двумя матрицами

Вот еще один метод, который я нашел, который строит две матрицы 3х3 из векторов и возвращает разницу.

Однако это медленнее, чем вычисление оси / угла, которое можно оптимизировать (упомянуто выше).

Заметка. это предполагает, что оба вектора нормализованы, матрица является главным по столбцу (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;
}

Есть ли лучшие способы выполнить этот расчет?

Редактировать: Цель этого вопроса - НЕ микрооптимизировать и не тестировать каждый метод. Вместо этого - мне было любопытно, есть ли какой-то совершенно другой и превосходный метод, о котором я не знал.

ЗаметкаЯ специально исключил проверки вырожденного случая для коллинеарных векторов (где ось равна нулевой длине), чтобы примеры были простыми.

Ответы на вопрос(2)

Ваш ответ на вопрос