Найти матрицу вращения OpenGL для плоскости, учитывая нормальный вектор после вращения

Есть ли способ получить матрицу, которая поворачивает плоскость к новой ориентации, учитывая ее новый нормальный вектор

На следующем рисунке изображено то, что описано

enter image description here

Ответ 1

Учитывая старый нормальный N и новый нормальный N', вы можете получить поворот на:

RotationAxis = cross(N, N')
RotationAngle = arccos(dot(N, N') / (|N| * |N'|))

Где

  • cross(x, y) является поперечным произведением векторов x и y
  • dot(x, y) является точечным произведением векторов x и y
  • |x| - длина вектора x

Это приведет к повороту старого нормального на новый с помощью кратчайшего пути.

Примечания

  • RotationAngle будет в радианах (если arccos возвращает радианы, как это происходит в большинстве реализаций)
  • arccos является обратным косинусоидальной функции. Это необходимо, потому что dot(N, N') = |N| * |N'| * cos(RotationAngle) где RotationAngle - угол между векторами.
  • RotationAxis не нормируется
  • Если нормали нормализованы, деление на (|N| * |N'|) становится ненужным (фактически, если N нормализовано, вы можете оставить |N| продукта, а если N' нормализовано, оставьте |N'|)
  • Этот метод завершится с ошибкой, если N' = -N (так как существует бесконечное множество кратчайших путей)

Как это работает?

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

Таким образом, вектор RotationAxis будет нормалью плоскости, которая охватывает как N, так и N', а RotationAngle - наименьший угол между двумя упомянутыми ранее.

Итак, вращаясь вокруг RotationAxis с помощью RotationAngle, старый нормальный N поворачивается внутри плоскости на кратчайший путь к N'.