新しい法線ベクトルが与えられたときに、平面を新しい方向に回転させる行列を取得する方法はありますか?
次の画像は、説明されている内容を示しています

N古い法線と新しい法線が与えられると、N'次の方法で回転を取得できます。
RotationAxis = cross(N, N')
RotationAngle = arccos(dot(N, N') / (|N| * |N'|))
どこ
cross(x, y)xベクトルとの外積ですydot(x, y)xベクトルとの内積ですy|x|ベクトルの長さですxこれにより、可能な限り最短の方法で古い法線が新しい法線に回転します。
ノート
RotationAngleラジアンになります(ほとんどの実装でそうであるように、arccosがラジアンを返す場合)arccosは余弦関数の逆関数です。ここで、はベクトル間の角度dot(N, N') = |N| * |N'| * cos(RotationAngle)であるため、これが必要です。RotationAngleRotationAxis正規化されていません(|N| * |N'|)は不要になります(実際、正規化されている場合は積をN除外でき、正規化されている場合は除外できます)|N|N'|N'|N' = -Nこの方法は、 (最短の方法が無限にあるため)失敗します。それはどのように機能しますか?
最初の観察は、2つの法線が常に(少なくとも)両方が横たわっている1つの平面を定義するということです。それらを分割する最小の角度も、この平面内で測定されます。
したがって、ベクトルはとの両方をRotationAxis囲む平面の法線になり、は前述の2つの間の最小角度になります。NN'RotationAngle
したがって、古い法線によって回転するRotationAxisことにより、平面内で、に向かう最短経路上で回転します。RotationAngleNN'