Эффективный способ вычисления матрицы вращения 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;
}
Есть ли лучшие способы выполнить этот расчет?
Редактировать: Цель этого вопроса - НЕ микрооптимизировать и не тестировать каждый метод. Вместо этого - мне было любопытно, есть ли какой-то совершенно другой и превосходный метод, о котором я не знал.
ЗаметкаЯ специально исключил проверки вырожденного случая для коллинеарных векторов (где ось равна нулевой длине), чтобы примеры были простыми.