DirectXとOpenGLの回転行列、回転軸、回転方向

アルゴリズム
スポンサーリンク

はじめに

こんにちは!ハンドスピナーを最近買ったなたでです!

今日も勉強会をします。本日は、DirectXとOpenGLの軸の違いに焦点をあてて、回転行列をおさらいしてみましょう。


掛け算をする順番のおさらい

3D環境といえば、DirectX、OpenGLです。今回、回転用の標準関数を調査して比較していきたいと思いますが、まず基本的な掛け算のおさらいをしましょう。

以下は、DirectX と OpenGL の計算方法の違いを表しています。


DirectX では、横行列に対して正方行列を掛け算して、横行列を求めます。一方、OpenGL では、正方行列に縦行列を掛け算して、縦行列を求めます。


標準関数の中身

それでは、DirectX、OpenGLで用意されている回転用の標準関数について確認していきましょう。

※以下、rotateZの3行目の3列目は、正しくは1です。いつか直します。

DirectX

DirectXでは回転用の関数に、D3DXMatrixRotation(D3DXMatrixRotationX/D3DXMatrixRotationY/D3DXMatrixRotationZ) が用意されています。これらの関数で使用されている行列は以下の通りとなります。

参考

OpenGL

OpenGLでは、glRotate(glRotated/glRotatef) が用意されています。

OpenGL Programming Guideには、これらの標準関数で使用されている回転行列が記載されています。ただ記載されている行列は、DirectXの回転行列の転置行列となっています。以下に、OpenGLで使用されている行列を記載しますが、掛ける順序による違いを吸収するため、予め転置させたものを記載します。

回転行列の特徴

対角成分が1になっている部分がある

X軸用、Y軸用、Z軸用の行列を順番に見ていくと、対角成分が1となっている箇所があります。回転行列は、ベクトルに掛け算することで回転させることができますが、1となっている部分は、以前の位置と変わらないことを示します。

例えば、ベクトルa=[x,y,z]に行列rotateYをかけた場合、a[y] の位置は1を掛けるだけであるため、値は変わらないことになります。Y軸を中心に回転させるので、yの値が変わらないと考えればよいです。

Wikipediaにある2次元回転行列について

少し回転行列の仕組みについて丸投げしますが、Wikipediaを見ると2次元の回転行列が書いてあるため、一度読んでみてください。

上記が、2次元の回転行列ですが、少し注意する部分があります。この回転行列は、θはどちらの方向に回転するのでしょうか。

Wikipediaでは、下記のように書いてあります。

 ユークリッド空間の2次元空間では、原点中心の θ 回転(反時計回りを正とする)の回転行列」

実は、この記述はすこし正確ではありません。後程詳しく解説しますが、上記の回転行列は、「教科書でよくある次のような座標系」での反時計回りを指しています。回転を考える場合は、そもそもの座標系をきちんと考えておかないと、時計回りといっても、前提条件によって誤った行列になる可能性があります。

転置行列の特徴

2次元回転行列と、D3DXMatrixRotationglRotateの回転行列は似ています。どう似ているかといいますと、2次元の回転行列の転置行列になっているわけです。

回転行列は直行行列のため、転置させると逆行列となります。

従って2次元の回転行列の反時計回りなので、D3DXMatrixRotationglRotateは「時計回り?」といった疑問がわきます。というわけで、実際に回転方向を考えていきましょう。

回転方向

D3DXMatrixRotationglRotateは、実際にどのような回転方向になっているでしょうか。まず、疑問に思うのが、この2つの関数は、同じ行列のため、同じ回転方向であるなのか?という点です。実際考えてみると、そう単純に考えることはできません。回転方向を考えるためには、まず軸の方向の定義を考える必要があります。

奥がX軸のプラス

手前がX軸のプラス

上記のような場合の2種類の座標系がある場合を考えてみます。このとき、X軸の正方向で時計回りした場合、上の図と下の図とで、回転方向が変わってくるはずです。つまり、X軸での時計回りについては、Y軸とZ軸の正の方向を定義しないといけません。

例えば、2次元の回転行列では、Wikipediaに「 ユークリッド空間の2次元空間では、原点中心の θ 回転(反時計回りを正とする)」と記載されていますが、右がX、上がYと定義しておかないと、「反時計回りを正とする」とは言えないのです。

軸の定義

回転方向を考えるためには、軸の定義が重要であることが分かりました。ここではDirectXと、OpenGLの座標系について解説していきます。具体的には、DirectXが左手座標系、OpenGLは右手座標系となりますが、以下詳細を解説していきます。

DirectXの座標系と回転方向

DirectXの座標系は以下のような左手座標系になります。

上の図の座標系で各軸の方向を考慮すると、DirectX の関数は次のようになります。

D3DXMatrixRotationX

回転方向のプラスは、原点からX軸の正の方向を向いたときに、反時計回りをさす。

D3DXMatrixRotationY

回転方向のプラスは、原点からY軸の正の方向を向いたときに、反時計回りをさす。

D3DXMatrixRotationZ

回転方向のプラスは、原点からZ軸の正の方向を向いたときに、反時計回りをさす。

図に表すと以下のようになります。

行列の式を見る限り、時計回りに回転するにみえますが、軸を考慮すると反時計回りをすることが分かりました。

参考

OpenGLの座標系と回転方向

OpenGLの座標系は以下のような右手座標系になります。

これも同様に、OpenGL の glRotateをあてはめると以下のような回転方向になります。

glRotate X

回転方向のプラスは、原点からX軸の正の方向を向いたときに、時計回りをさす。

glRotate Y

回転方向のプラスは、原点からY軸の正の方向を向いたときに、時計回りをさす。

glRotate Z

回転方向のプラスは、原点からZ軸の正の方向を向いたときに、時計回りをさす。

図に表すと以下のような右ねじの法則みたいになります。

座標系の違いと回転行列

最初に回転行列を見ると、DirectXとOpenGLは同じにみえました。しかし、座標系が異なっており、Z軸のみが反転している関係があることから、DirectXとOpenGLとで、X軸とY軸の回転の向きが逆向きになっています。Z軸のみは、そもそも方向自体が逆になっているため、Z軸の回転方向の見た目上の動きは、DirectXとOpenGLとで同様の回転方向になります。

おわりに

今回、DirectXとOpenGLの標準関数の回転行列の式の解説、そして、DirectXとOpenGLの座標系を比べて、正方向が時計回りか反時計回りかを調べました。DirectXとOpenGLは、Z軸の方向が逆という話はよくききますが、見た目上の回転方向にも違いがあるという点はそんなにききません。両方を考える場合は、これらを注意する必要があります。


おすすめの勉強本

コメント

タイトルとURLをコピーしました