Есть ли способ получить матрицу, которая поворачивает плоскость в новую ориентацию, учитывая ее новый вектор нормали
На следующем изображении изображено то, что описано
Есть ли способ получить матрицу, которая поворачивает плоскость в новую ориентацию, учитывая ее новый вектор нормали
На следующем изображении изображено то, что описано
Учитывая старую нормаль 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'
.