クォータニオン(四元数、Quaternion)は3Dグラフィックスのプログラミングにおいて回転を表す数としてよく出てきます。
曰く、
- サイズが小さい(回転行列よりも少ない数で表せる)
- ジンバルロックが起きない
- 補間が容易
とのことで、非常に便利な理論です。
しかし、どういう原理で動いているのかを知りたいと思ってWikipediaなんかを見ると、大量の数式と謎の言葉の波に飲み込まれます。
そんなこんなで今までよくわからないままに使っていたのですが、 最近になって少しだけ理解が深まったので、現時点で知っていることについて説明してみようと思います。
対象読者
クォータニオンがどういうものなのか知りたい人向けです。 単にクォータニオンを利用した回転方法を知りたいだけであれば、他の資料を当たった方が簡単だと思います。
あまり難しい計算はしませんが、高校数学くらいの知識は持っているものとします。 具体的には、複素数、三角関数、ベクトル、行列についてです。
とはいえ、そんなによく理解していなくてもどうにかなるように書いたつもりです。
複素数と座標
クォータニオンの話に入る前に準備として複素数の話をします。 というのも、クォータニオンというのは複素数の拡張だからです。
複素数というと確か
複素数は一般に
そこで、
2次元ベクトルが2次元座標を表すように、複素数もまた2次元座標を表すことができる2次元的な数なのです (ベクトルというと矢印や座標を思い浮かべるかもしれませんが、ベクトルの意味は単なる一並びの数であって、プログラミングにおける一次元配列に相当します)。
複素数と回転
複素数が2次元座標を表せることはわかりました。 しかし、ベクトルではなく複素数を使う利点とは何でしょうか。 それは複素数の掛け算によって回転が簡単に表せることなのです (内積や外積により角度や直交方向が表せるのと同じ)。
ベクトルによる座標表現の場合、回転は回転行列を用いて次のように表せました。
これは座標
さて、ここで次の複素数の計算式を見てください。
なんとなく先ほどの式に現れていたような部分が見て取れるのではないでしょうか。
左辺右側の複素数と右辺の複素数をそれぞれ座標だと考えると、左が回転前の座標、右が回転後の座標になっています。
回転行列の式と見比べると、
天下り的な説明*1ではありますが、
複素数で回転を表せるということがわかりました。
ちなみに、どんな複素数でも回転を表すというわけではなく、絶対値(
クォータニオンの定義
複素数は2次元的な数で、2次元の回転を表すことができました。 ということは、3次元版の複素数を考えれば3次元の回転ができるんじゃないか、というのは自然な発想ではないでしょうか。 しかし、実は複素数を3次元に拡張するのは満たすべき性質を考えると数学的に難しいことでした。 それならばと、ひとつ飛ばして4次元にまで拡張した複素数がクォータニオンです*2。
クォータニオンは1つの実部と3つの虚部からなる数です。
3つの虚部が必要ということで、
計算方法は概ね複素数と同じですが、乗算では
ただし、クォータニオンでは行列の乗算のように右からかけるか左からかけるかで計算結果が異なります(交換法則が成立しない)。
上の定義に右から左から適当な数(
複素数が2次元座標を表現できたように、クォータニオンも4次元座標を表現できます。
例えば、座標
クォータニオンと回転
結論だけいうと、絶対値(
しかし、改めて考えてみると4次元の回転というのはいったいどんな操作なのでしょうか。
それを確かめるためにクォータニオン
これはつまり、次の座標変換を表しています。
ここで、実部と
また、この計算結果にはクォータニオンによる回転の重要な性質が現れています。 それは1点で交わる2つの平面*3上で同じ大きさの角度だけ回転させるというものです(isoclinic rotation)。 4次元空間における回転にもいくつか種類があるのですが、1つのクォータニオンの乗算で表現できる種類の回転はこれになります。
座標平面上の回転
先ほどは
同様にして、
まとめると次のようになります。
を左からかけると 平面と 平面が角度 回転 を左からかけると 平面と 平面が角度 回転 を左からかけると 平面と 平面が角度 回転
乗算方向による回転の変化
クォータニオンの乗算では左右どちらからかけるかによって計算結果が異なるのでした。 回転操作は乗算なので、当然この影響を受けます。
変化を確かめるために
計算過程からわかるように、異なる二つの虚数単位の積が逆転することにより正負が反転し、
結果として
他の座標平面に対する結果も合わせて次にまとめます。
を右からかけると 平面が角度 回転、 平面が角度 回転 を右からかけると 平面が角度 回転、 平面が角度 回転 を右からかけると 平面が角度 回転、 平面が角度 回転
共役クォータニオンによる回転
あるクォータニオンに対して、虚部の符号を反転させたクォータニオンを共役クォータニオンといいます。
クォータニオン
定義より、
一般に回転を表すクォータニオンの共役クォータニオンは逆向きの回転を表します。 実部まで符号を反転させてしまうと逆回転にならないため注意してください *4。
回転の合成
回転操作は乗算であり、クォータニオンの乗算には結合法則が成り立ちます。
よって、座標
つまり、回転を表すクォータニオン同士の乗算により回転の合成ができるのです。
また共役クォータニオンには
クォータニオンの乗算は左右どちらからかけるかによって結果が変わってしまうため、 合成の際には座標に対してどちらから回転を適用するかを考慮した上で、回転の順番を意識する必要があります。
クォータニオンと3次元回転
さて、ここまでは4次元の回転を考えてきましたが、我々が扱いたいのは3次元の回転です。 クォータニオンによる回転操作でどのように3次元の回転を実現するかを考えていきます。
3次元座標と4次元座標
クォータニオンによる回転操作は4次元空間にて適用するため、 3次元の座標は4次元の座標に変換する必要があります。
言葉にするとなんだか難しそうですが、やることは簡単で
仮に
回転後の座標を表すクォータニオンも逆の手順で3次元座標へと変換できます。
回転の適用
前節では、各座標平面上の回転を表すクォータニオンを紹介しました。
これらは
しかし、そうなると邪魔になってくるのが、同時に回転してしまう
これを解消する方法は単純で、逆方向の回転によって打ち消してしまうことです。 具体的には次に示す演算をします。
一方、
各軸周りに対して、同じ操作をすると次のようになります。
よって、各軸周りの回転を合成したクォータニオン
さて、この
計算手順のまとめ
- 3次元座標
をクォータニオン に変換 を回転軸として角度 回転させるクォータニオン を計算- 回転後の座標を表すクォータニオン
を計算 を3次元座標 に変換
クォータニオンと回転の一意性
4次元の回転において異なるクォータニオンが同一の回転を表すことはありません。 クォータニオンが表現できる種類の回転に対して、対応するクォータニオンは一意に定まります。
一方で、3次元の回転においては異なるクォータニオンが同一の回転を表すことがあります。 これは3次元回転の実現方法に起因しています。
3次元の回転ではひとつの平面における回転を打ち消すためにクォータニオンを二回乗算する必要がありました。
そもそもクォータニオンによる乗算は一回で
回転を表すクォータニオンの計算式に
このように、3次元において同じ回転を表すクォータニオンは二つずつ存在するため、 クォータニオンが一致しないからといって異なる回転だと判断してはいけません。
クォータニオンの補間
クォータニオンを回転に利用する大きな動機のひとつは補間が容易であることです。
よく使われるクォータニオンの補間に球面線形補間(spherical linear interpolation, slerp)と線形補間(linear interpolation, lerp)があります。
球面線形補間
球面線形補間はクォータニオンにおける基本的な補間です。
回転を表すクォータニオンは絶対値が1であるのでした。
回転を表すクォータニオンを座標だと考えて4次元空間に配置すると、
4次元で考えづらい場合には、徐々に次元を上げていくとわかりやすいかもしれません。 2次元においては、円上の二点の間を、常に円上を通るように一定速度で移動するような補間です。 3次元になると球面上の二点の間を球面上を通るように移動する経路は無数にありますが、そのうちの最短の経路を一定速度で移動するような補間です。 4次元空間がどんな世界なのかは想像もつきませんが、同じような補間がきっとできるはずです。
球面線形補間を式にすると次の通り。
を満たす
回転を表すクォータニオンでは絶対値が1なので、それらの内積の値は
線形補間
球面線形補間はきれいな補間ができるのですが、式をみればわかるようにそれほど単純な計算ではありません。 プログラミングにおいて、膨大な回数をこなすには少し計算量が多いのです。 そこで、近似的に少ない計算量で球面線形補間を実現する方法が線形補間です。
球面線形補間では超球面上を通るように補間しましたが、線形補間では直線経路で補間します。 直線経路で補間すると、補間結果のクォータニオンは基本的に超球面上にはありません。 つまり、回転をあらわすクォータニオンでなくなってしまいます。 これでは困るため、結果のクォータニオンをその絶対値で割ってやることで、絶対値が1になるように(半径1の超球面上に乗るように)正規化します。
線形補間を式にすると次の通り。
この式は球面線形補間の式における、
補間における注意
クォータニオンの補間には一点だけ注意しておかなければならないことがあります。 それは、同じ回転を表すもうひとつのクォータニオンの存在です。
前節で述べたとおり、3次元の回転を表すクォータニオンは符号を反転させると、 まったく同じ回転を表すもうひとつのクォータニオンになります。 これらは3次元の回転としては同じでも、4次元空間における位置は原点を挟んでまったくの逆側です。 当然、どちらのクォータニオンとの間を補間するかによって結果はまったく異なります。
基本的に補間は距離の短い経路を用いた方が直感的になるため、
3次元の回転を表すクォータニオン同士を補間する場合には、符号をうまく反転させて近いクォータニオン同士を補間します。
どちらのクォータニオンの方が近いか判定するには角度を利用します。
二つのクォータニオンの内積を計算して、値が正なら
参考
- 四元数を用いた三次元回転計算の幾何学的意味
- Why Do Quaternions Double-Cover? – Nathan Reed’s coding blog
- https://www.essentialmath.com/GDC2013/GDC13_quaternions_final.pdf
おわりに
クォータニオンに関する記事は、使い方のみに焦点を絞ったものや難しい数学の原理を説明したものが多く、 これら二つの間を埋めるような内容の記事が少ないな、と思ったので書いてみました。 できる限りわかりやすくする、という名目のもと難しい説明が必要な内容を(重要さに関わらず)片っ端からすっ飛ばしたので、 この記事を読んだだけでは疑問点も多いかもしれませんが、他の数学的記事の理解の助けになれば幸いです。
実はこの記事、うまい説明の流れが思いつかずに数か月間積んでます。 そのままお蔵入りにするのももったいないので、とりあえず書き残したことを加筆したのですが、 当初の構成を覚えていないのでバグ(論理の破綻)が紛れ込んでいる可能性が多分にあります。 何かおかしな点を見つけたら指摘してもらえると助かります。