始めに
過去記事
Quaternionの解説をしようと思いましたが、今回はロドリゲスの回転公式を扱っていこうと思います。
この内容と同時にQuaternionをやっていこうと当初は予定していましたが、四元数の解説が予想より長くなりそうなので2回に分けてQuaternionは次回に回します。
ロドリゲスの回転公式
ロドリゲスの回転公式とは「ベクトル空間において、与えられた回転軸に対して回転を行うための効率的なアルゴリズムを指す。」というものです。(wikipediaより)
図で解説すると次のようになります。 (頑張って書いたけど汚い. . . .)
あるベクトル を単位ベクトル を軸に だけ回転して を得ます。
ベクトル を の垂直成分と平行成分の和に書き換えることが出来ます。
次に、この2つのベクトルを書き換えていきます。平行成分のベクトルは と の内積を使って求められます。
垂直成分についても書き換えていきます。 先ほど求めた平行成分のベクトルを利用します。
次に の平行成分と垂直成分に垂直なベクトル を求めます。 は と の垂直成分の外積を使用することで求められます。
では と の垂直成分を利用して の垂直成分を求めます。これは2次元の回転と同じ計算になります。
最後に回転して得られるベクトル は次のようになります。
変換行列にする
と を次のようにする。
では、ここから表現行列を求めます。先程求めた回転公式を少し整理します。
次にこれらの記事を参考に変換行列を求めます。(本の内容よりもこちらの方が分かり易いと感じました)
求められた変換行列は次のようになります。
シェーダーで実装
この変換行列をシェーダーで実装してみます。
float3 rotation(float3 vertex, float3 Axis, float theta) { float t = radians(theta); float cosValue = cos(t); float sinValue = sin(t); float a = 1 - cosValue; float3 axis = normalize(Axis); float3x3 mat = float3x3( float3(axis.x * axis.x * a + cosValue, axis.x * axis.y * a - axis.z * sinValue, axis.x * axis.z * a + axis.y * sinValue), float3(axis.x * axis.y * a + axis.z * sinValue, axis.y * axis.y * a + cosValue, axis.y * axis.z * a - axis.x * sinValue), float3(axis.x * axis.z * a - axis.y * sinValue, axis.y * axis.z * a + axis.x * sinValue, axis.z * axis.z * a + cosValue)); return mul(vertex, mat); } v2f vert (appdata v) { v2f o; v.vertex.xyz = rotation(v.vertex.xyz, _Axis, _Theta); o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; }
結果が次のgif動画になります。
過去記事と同様に、座標変換やスケーリングと組み合わせることも可能です。
v2f vert (appdata v) { v2f o; float4x4 scale = float4x4( float4(_ScaleX, 0, 0, 0), float4(0, _ScaleY, 0, 0), float4(0, 0, _ScaleZ, 0), float4(0, 0, 0, 1)); v.vertex = mul(scale, v.vertex); v.vertex.xyz = rotation(v.vertex.xyz, _Axis, _Theta); v.vertex.x += _PosX; v.vertex.y += _PosY; v.vertex.z += _PosZ; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; }
最後に
ロドリゲスの回転公式についてまとめました。個人的な感想になりますが、「ロドリゲスの回転公式」って滅茶苦茶かっこいい名前ですよね。
次回はQuaternion(四元数)についてまとめていく予定です。
追記
最後にQuaternionをまとめました。