前回からの続き。
前回はモーションブレンディング時の回転の補完で、複数のクォータニオンからひとつのクォータニオンを作るのに exp マップというのが必要というところまで説明しました。
そんな exp マップの実装方法ですが、、、
実はそんなに難しくありません。
対数空間上で混ぜ合わせ、その結果を実空間に戻すだけです。
・・・内容がこれだけじゃわかりませんね。
僕もなんでこれで正しく処理できるのか?がいまいち理解し切れませんでした。
まず対数空間とは何でしょうか?
その前に大前提として、クォータニオンは複素数の仲間です。
複素数の有名な公式のひとつにオイラーの公式があります。
っていうか、公式の中でもっとも有名な式だと思います。
e^iθ = cosθ+ i sinθ
ってやつですね。
これを利用して、クォータニオンの自然対数を決めてみます。
回転を表す単位クォータニオン は
q = cosθ + v sinθ
ですね。
v は
ii = jj = kk = -1
ij = k
jk = i
ki = j
ijk = -1
の関係式を持つ複素ベクトルです。
オイラーの公式を使って、この q の自然対数を取ってみましょう。
ln(q) = ln ( cosθ + v sinθ )
= ln ( e^vθ )
= vθ
上記の式変形から、クォータニオンの自然対数は複素ベクトル部に角度θをかけた物になるということがわかるかと思います。
同様に自然対数からの逆変換は、q の長さが θ になりますので、
exp(q) = cos |q| + v / |q| sin |q|
と書くことができます。
これで対数空間への変換と逆変換がわかりました。
後は対数空間上で混ぜ合わせればいいだけです。
具体的にやってみましょう。
今 q1 と q2、q3 をそれぞれ、0.3、0.5、0.2 で混ぜ合わせ、新しい qt というクォータニオンを作りたいと思います。
擬似コードは以下のようになります。
qt = exp( ln(q1) * 0.3 + ln(q2) * 0.5 + ln(q3) * 0.2 )
クォータニオンは積の結合則は成り立ちませんが、和の結合則は成り立ちますので、
qt = exp( ln(q2) * 0.5 + ln(q1) * 0.3 + ln(q3) * 0.2 )
こんな感じに入れ替えても ok です。
(可換性といいます)
数学理論的になぜこれが正しいのか?はわかってません('A`)
対数空間で加算してから実空間に戻すのと、実空間での積との間には関連がないからです。
(積の結合則が成り立たないため)
ただ、この手法を使えば複数のクォータニオンのブレンディング時に特異点が発生するのは回避できますし、長さが変化しないのも保障されるので、使い勝手はものすごくいいです。
モーションブレンディングに悩んでいる方は使ってみてください。
ちなみに、元になった論文は
http://www.cs.cmu.edu/~spiff/moedit99/expmap.pdfにあります。
もし数学的にも完全にわかったら教えてくださるとうれしいですw
最近のコメント