デュアルクォータニオンの球面線形補間

2つのデュアルクォータニオン
\begin{eqnarray*}
d_1 & = & r_1 + \epsilon q_1, \\
d_2 & = & r_2 + \epsilon q_2
\end{eqnarray*}
を補間することを考えてみましょう。ここで \(d_1,\ d_2\) は大きさが1のデュアルクォータニオン、つまり、\(r_1,\ r_2\) は回転をあらわす大きさが1のクォータニオンで、\(q_1,\ q_2\) は
\begin{eqnarray*}
r_1 \cdot q_1 & = & 0, \\
r_2 \cdot q_2 & = & 0 \\
\end{eqnarray*}
を満たすクォータニオンとします。

クォータニオン徹底解説の最後のページ では、理想の補間がどうあるべきかについて議論してクォータニオンの球面線形補間を導きました。ここでも同じ議論を適用して、
$$ d_2 d_1^{-1} \equiv d_3 = \left(\cos\beta,\ \sin\beta\,\vec{\alpha}\right) $$
となるような \(\vec{\alpha},\ \beta\) をみつけて、\(d_1,\ d_2\) をパラメータ \(\tau\) で補間したデュアルクォータニン \(d(\tau)\) を
$$ d(\tau) = \left(\cos \tau\beta,\ \sin \tau\beta\,\vec{\alpha}\right) d_1 $$
として計算します。

\(d_3\) は \(d_1\) であらわされる状態を \(d_2\) であらわされる状態に遷移するデュアルクォータニオンになので、\(d(\tau)\) は \(\tau\) が0から1に近づくにつれて、回転軸を固定したままらせん運動をして状態 \(d_1\) から状態 \(d_2\) に移る関数になっています。そのため、空間全体でみれば、最短短経路で状態を遷移させる補間になっています(※)。

クォータニオンの補間のときとの違いは、\(\vec{\alpha}\) や \(\beta\) が二重数になっていることだけなので、クォータニオンのときとまったく同じ計算で、\(d(\tau)\) を \(\beta\) を使って次のように書くことができます。
\begin{eqnarray*}
d(\tau) & = & \left\{\cos \tau\beta + \sin \tau\beta\,\frac{d_2 d_1^{-1} – \cos\beta}{\sin\beta}\right\} d_1 \\
& = & \frac{\sin \tau\beta}{\sin\beta} d_2 + \frac{\sin\beta \cos \tau\beta\ – \cos\beta \sin \tau\beta}{\sin\beta} d_1 \\
& = & \frac{\sin \tau\beta}{\sin\beta} d_2 + \frac{\sin{(1-\tau)\beta}}{\sin\beta}d_1
\end{eqnarray*}
最後の式変形で、\(\sin{(A-B)} = \sin A \cos B\ – \cos A \sin B\) となることを使っていますが、これが二重数でも成り立つかどうか不安な人は \(f(x + \epsilon y) = f(x) + \epsilon y f'(x)\) となることを使って確かめてみてください(テイラー展開の形が同じになるので、確かめなくても成り立つはずですが)。

\(\beta\) は \(d_3\) のスカラー成分から計算します。\(d_3\) を求めるためにはデュアルクォータニオンの逆変換 \(d_1^{-1}\) が必要ですが、\(d_1\) は大きさが1のデュアルクォータニオンなので、
$$ |d_1|^2 = d_1 \overline{d_1} = 1 $$
です。つまり、回転と移動をあらわすデュアルクォータニオンの逆変換は、回転をあらわすクォータニオンと同じように、
$$ d_1^{-1} =\overline{d_1} $$
となります。

これを用いて \(d_3\) を計算すると
\begin{eqnarray*}
d_3 & = & d_2 d_1^{-1} \\
& = & r_2 \overline{r_1} + \epsilon\left(q_2 \overline{r_1} + r_2 \overline{q_1}\right)
\end{eqnarray*}
が得られます。ここからスカラー成分を取り出して、
$$ \cos\beta = r_1 \cdot r_2 + \epsilon\left(r_1 \cdot q_2 + q_1 \cdot r_2\right) $$
と計算できます。

ここで、
$$ \beta = \Theta + \epsilon L $$
と書くことにすると、
$$ \cos\beta = \cos\Theta\ – \epsilon L \sin\Theta $$
となるので、\(\Theta,\ L\) は次のようになります。
$$
\cos\Theta = r_1 \cdot r_2, \\
L \sin\Theta = -\left(r_1 \cdot q_2 + q_1 \cdot r_2\right)
$$

これらを用いて、\(d(\tau)\) を \(r + \epsilon q\) の形に書き換えてみましょう。
\begin{eqnarray*}
\frac{\sin t\beta}{\sin\beta} & = & \frac{\sin \tau\Theta + \epsilon \tau L \cos \tau\Theta}{\sin\Theta + \epsilon L \cos\Theta} \\
& = & \frac{\sin \tau\Theta + \epsilon \tau L \cos \tau\Theta}{\sin\Theta}\left(1 – \epsilon L \frac{\cos \tau\Theta}{\sin\Theta}\right) \\
& = & \frac{\sin \tau\Theta}{\sin\Theta}\left(1 + \epsilon L \sin\Theta \cos \tau\Theta \frac{\tau\sin\Theta\ – \sin \tau\Theta}{\sin^2\Theta}\right)\\
& = & \frac{\sin \tau\Theta}{\sin\Theta}\left\{1 – \epsilon \left(r_1 \cdot q_2 + q_1 \cdot r_2\right) F(\Theta,\ \tau)\right\}
\end{eqnarray*}
$$ F(\Theta,\ \tau) \equiv \cos \tau\Theta\, \frac{\tau\sin\Theta\ – \sin \tau\Theta}{\sin^2\Theta} $$
と書けば、
\begin{eqnarray*}
d(\tau) & = & \frac{\sin \tau\beta}{\sin\beta} d_2 + \frac{\sin{(1-\tau)\beta}}{\sin\beta}d_1 \\
& = & \frac{\sin \tau\Theta}{\sin\Theta} \left\{r_2 + \epsilon q_2\ – \epsilon F(\Theta,\ \tau)\left(r_1 \cdot q_2 + q_1 \cdot r_2\right) r_2\right\} \\
& & + \frac{\sin (1-\tau)\Theta}{\sin\Theta} \left\{r_1 + \epsilon q_1\ – \epsilon F(\Theta,\ 1-\tau)\left(r_1 \cdot q_2 + q_1 \cdot r_2\right) r_1\right\} \\
\end{eqnarray*}
となります。

ここで念の為、\(\Theta \rightarrow 0\) の極限で \(F(\Theta,\ \tau)\) が発散しないことを確認しておきます。
$$ \lim_{\Theta \rightarrow 0} F(\Theta,\ \tau) = \frac{\tau\left(\Theta\ – \frac{1}{3!}\Theta^3\right) – \left(\tau\Theta\ – \frac{1}{3!}\tau^3 \Theta^3\right)}{\Theta^2} = -\frac{\tau \left(1-\tau^2\right)\Theta}{3!} = 0 $$

また、\(\delta(\Theta,\ \tau)\) は \(\tau = 0\) のときと \(\tau = 1\) のときには 0 となります。

それにしても、この補間はちょっと計算が大変ですね。スキニングにデュアルクォータニオンを使う場合、ポリゴンの頂点毎にこの計算をしないといけないため、ゲームには向きません。そこで、Kavan らはデュアルクォータニオンを線形補間して正規化する方法で代用しました。この方法で得られるデュアルクォータニオン \(d_{LN}(\tau)\) は、
$$ d_{LN}(\tau) = \frac{\tau d_2 + (1-\tau) d_1}{|\tau d_2 + (1-\tau) d_1|} $$
と書けます。

ここで、
\begin{eqnarray*}
r_L(\tau) & = & \tau r_2 + (1-\tau) r_1, \\
q_L(\tau) & = & \tau q_2 + (1-\tau) q_1
\end{eqnarray*}
と書くことにすれば、
\begin{eqnarray*}
d_{LN}(\tau) & = & \frac{r_L(\tau) + \epsilon q_L(\tau)}{|r_L(\tau)| + \epsilon \frac{r_L(\tau) \cdot q_L(\tau)}{|r_L(\tau)|}} \\
& = & \frac{r_L(\tau) + \epsilon q_L(\tau)}{|r_L(\tau)|} – \epsilon \frac{(r_L(\tau) \cdot q_L(\tau)) r_L(\tau)}{|r_L(\tau)|^3}
\end{eqnarray*}
となり、
\begin{eqnarray*}
r_{LN}(\tau) & = & \frac{r_L(\tau)}{|r_L(\tau)|}, \\
q_{LN}(\tau) & = & \frac{q_L(\tau)}{|r_L(\tau)|}
\end{eqnarray*}
と置くことで、
$$ d_{LN}(\tau) = r_{LN}(\tau) + \epsilon\left\{q_{LN}(\tau)\ – \{r_{LN}(\tau) \cdot q_{LN}(\tau)\} r_{LN}(\tau)\right\} $$
と記述できます。

補間された回転は \(r_{LN}(\tau)\) であり、補間された移動量 \(t_{LN}(\tau)\) は
$$ d_{LN} = r_{LN} + \frac{\epsilon}{2}t_{LN}r_{LN} $$
の形式から
\begin{eqnarray*}
t_{LN}(\tau) & = & 2 \left(d_{LN} – r_{LN}\right)\overline{r_{LN}} \\
& = & 2 \epsilon \left\{q_{LN}(\tau) \overline{r_{LN}}(\tau)\ – r_{LN}(\tau) \cdot q_{LN}(\tau)\right\}
\end{eqnarray*}
となります。欲しいのは、このベクトル成分であり、スカラー成分は0になるはずです。ですので、計算する必要があるのは
$$ 2 q_{LN}(\tau) \overline{r_{LN}}(\tau) = \frac{2 q_{L}(\tau) \overline{r_{L}}(\tau)}{|r_L|^2} $$
だけであり、このベクトル成分が移動量ベクトルになります。

線形補間されたデュアルクォータニオンを正規化して、回転量と移動量を取り出すプログラムをシェーダー言語(HLSL)を使って示しておきましょう。

この方法であればゲームのスキニングにも使うことができるくらいシンプルです。

でも正しい補間との誤差が気になりますよね? Kavanらの評価によれば、回転角度で 8.15 度未満の誤差、移動では 15.1% の未満の誤差に収まるそうです。15.1% ってだいぶ大きいように思いますが、物理シミュレーションをしているわけではなく、グラフィックスで使うだけなので、その程度の誤差は許容して、パフォーマンスを重視するのがよいでしょう。それに、こんな誤差よりもデュアルクォータニオンの補間の性質を持っていることの方が重要なのです。

(※) 状態 \(d_1\) から状態 \(d_2\) に最短経路で遷移するというのは、ちょっとわかりにくいかと思います。空間上の点を遷移させるのであれば、直線で移動するのが最短経路となるはずですが、そのような経路の補間を回転と移動の演算のみで行なおうとすると、点の位置に依存した演算になってしまいます(行列の線形補間ならこのような経路になりますが回転と移動のみではあらわせません)。また、何か大きさのある剛体の状態を遷移させる場合も、剛体の形状や位置に依存したもっと効率のよい経路となる補間があるかもしれません。ここで最短経路と言っているのは、空間全体を回転と移動のみで遷移させたときの各点の経路の長さの総和が最小になるということです。必ずしもこの経路があらゆる場合において自然で最適な遷移になるとは限りませんが、どのような場合においてもそれなりに良いものになると考えられます。

4 thoughts on “デュアルクォータニオン徹底解説

  • 2018/09/13 at 2:03 PM
    Permalink

    大変すばらしい解説、ありがとうございました。
    ロボット工学で良く出てくるので、すごい参考になりました。

    Reply
    • 2018/09/17 at 10:43 AM
      Permalink

      ロボット工学では良く使われるのですね。知りませんでした! コメントありがとうございます。

      Reply
  • 2018/11/12 at 5:39 AM
    Permalink

    いつも大変お世話になっております。
    3ページ目の
    回転と移動をあらわした行列 A は Z の指数関数で表現できます。
    A=eZ

    そして、この行列 A に対応したデュアルクォータニオン d は
    d=e^θ(axi+ayj+azk)+ϵ(vxi+vyj+vzk)

    で計算できます。
    の部分の質問なんですがこの文が書かれていたところの前に書かれていた文書のi,j,kとX,Y,Zの対応関係で出てきた1/2はどこに消えたのですか?

    Reply
    • 2018/11/12 at 11:48 AM
      Permalink

      ご指摘の通り、1/2が抜けていましたので修正いたしました。
      ありがとうございます!

      Reply

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Anti Spam Code *