スポンサーサイト

--年--月--日 --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Exponential Map

2009年02月18日 00:16

前回からの続き。

前回はモーションブレンディング時の回転の補完で、複数のクォータニオンからひとつのクォータニオンを作るのに 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
スポンサーサイト

またまた

2009年02月17日 00:26

一ヶ月ぶりぐらいの日記です('A`)
うーん。。なかなか記事となるネタがないんですよね~。。

とりあえず、exp マップを紹介します。


膝を思いっきり曲げて歩くモーションと普通に歩くモーション、それと走るモーションの3つを組み合わせて中腰で小走りに走るモーションを作りたい!なんて時があるかもしれません(なかなかないけど)

そんな時、モーションをいい感じにブレンドして処理できれば素敵ですよね。
モーフィングみたいに複数のモーションからひとつのモーションを作り出すような感じで。
そんなときに使うのがこの exp マップです。

なぜこの技術が必要なのか?
その原因がクォータニオンです。
最近のゲームでは姿勢の制御や回転アニメーションはもっぱらクォータニオンで行っています。

クォータニオンを使ってる場合、ただ単にそれぞれの要素を線形補完してしまうと、長さが変化してしまいます。
長さがあるうちは単位化してしまえば何とかなりそうですが、長さが 0 になることもありうるわけです。
そうなると、単位化時に 0 除算エラーを招いてしまいます。
長さを保つ球面線形補完を使えばいいじゃんって思うかもしれませんが、球面線形補完は2つの間を補完するためだけにしか使えません。


そもそもなぜクォータニオンを使うのか?
クォータニオン以外の方法で回転を表す方法にオイラー角というのがあります。
ロール、ピッチ、ヨーの3この角度で制御するやつですね。
クォータニオンなんかより直感的に解り易いですし、データの数も少ないです。
しかし、このオイラー角、実は特異点があるという問題があります。
ロール→ピッチと処理した後ヨーの回転を行うとき、ヨーの回転軸がロールかピッチの軸とかぶってしまった場合、ジンバルロックというヨーの回転が意味を成さない(何も回転しない)現象がおきてしまうからです。
一自由度減ってしまうわけですね。

他にオイラー角から行列を作成するのは積算の回数が多いので、あまり効率的じゃないというのもあります。


さて、そんな問題を一気に解決する exp マップの方法なんですが、、、、
これは折角のネタなので次の回にまわしたい思います。


最近の記事


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。