新しい法線ベクトルが与えられたときに、平面を新しい方向に回転させる行列を取得する方法はありますか?
次の画像は、説明されている内容を示しています
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
この方法は、 (最短の方法が無限にあるため)失敗します。それはどのように機能しますか?
最初の観察は、2つの法線が常に(少なくとも)両方が横たわっている1つの平面を定義するということです。それらを分割する最小の角度も、この平面内で測定されます。
したがって、ベクトルはとの両方をRotationAxis
囲む平面の法線になり、は前述の2つの間の最小角度になります。N
N'
RotationAngle
したがって、古い法線によって回転するRotationAxis
ことにより、平面内で、に向かう最短経路上で回転します。RotationAngle
N
N'