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

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

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

введите здесь описание изображения


person rraallvv    schedule 02.11.2012    source источник


Ответы (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'.

person Nobody moving away from SE    schedule 02.11.2012
comment
+1, но вы можете опустить деление на (|N|*|N|), поскольку векторы нормалей имеют длину 1. - person AD-530; 02.11.2012
comment
@ AD-530 AD-530 Как написано в примечаниях :) Но я отредактировал это, чтобы теперь было более понятно. Нормали не нужно нормализовать, они должны быть только перпендикулярны плоскости. - person Nobody moving away from SE; 02.11.2012
comment
Большое спасибо, это мне очень помогло - person rraallvv; 03.11.2012