NOBのArduino日記!

NOBのArduino日記!

趣味は車・バイク・自転車・ラジコン・電子工作です。

3DCGをプログラム!(アフィン変換)

イメージ 10
図1:「アフィン変換」による3D表示(ディスプレイの座標と物体のイメージ)
 
イメージ 11
図2:「透視投影変換」による3D表示(ディスプレイの座標と物体のイメージ)
 
 先日の記事で作った「ストランドビースト」2次元シミュレートモデル(プログラム)を3次元シミュレートモデルに1次元UPさせたいです!
 と言う事で3DCGの基礎から勉強してみました!

1. 3D座標計算とは?

 3DCGや3DCADにおいてオブジェクトが移動したり回転したりする際には座標変換が行われています。
 代表的な座標変換方式として「アフィン変換」※1「透視投影変換」※2があります。
 
以下補足です

※1:「アフィン変換」とは、3DCG3DCAD等において、モデル座標→ワールド座標→カメラ座標の座標変換を行う際に使用される平行移動と線形変換による座標変換方式の一種。線形変換である事から座標を変換しても線の長さの比は変わりません。(図1参照)
 
 
※2:「透視投影変換」と呼ばれる座標変換方式は遠くのものほど小さくなる為線の長さの比が変わる。(図2参照)
 
※:図1,2の3DCAD作成にはTINKERCADを使用。

2. アフィン変換!

 和歌山大学さんで出されている座標変換に関する資料を参考にさせて頂きました。大変勉強になりました有難う御座います。
 こちらの詳しい資料を基に一番基本的な3DCG座標変換手法である「アフィン変換」に関する要点だけまとめてみました
 
2.1 実座標
「実座標」とは、表現しようとするxyz3軸で構成される3次元空間における点の位置を表します。(式①)
イメージ 1
 
2.2 同次座標
「同次座標」とは、「実座標」xyzにωを加えて点の座標を表すものです。(式②)
ω=1を加える事で座標計算を簡素化出来たり、ω=0を加える事で原点からの方角を計算する事が出来などの利点があります。イメージ 2
 
2.3 変換行列
「変換行列」とは、「同次座標」に掛け合わせる事で座標を変換(移動・回転・拡大・変形等)する事が出来ます。(式③)
 0m15の値に回転角度や移動距離等を使用した関数や01等を代入する事で、様々な座標変換機能を持たせる事が可能です。
 参考に基本的な「平行移動」・「X軸中心の回転」・「Y軸中心の回転」・「Z軸中心の回転」に用いる「変換行列」について⑴~⑷に示します。
イメージ 3

イメージ 4

2.4 変換座標
「変換座標」V’とは、「同次座標」V(式②)に「変換行列」M(式③)を掛ける事で座標変換された値です。
「変換座標」V’を式で表したものを式④に示します。
イメージ 5

3. 例題

 今私がやりたい事を自分で例題にして自分で解答してみました
 
〇例題
「実座標」V(xyz)に有る点を、原点O(Ox,Oy,Oz)から延びるY軸を中心にθ°回転させる。
この時の点V(xyz)がディスプレイのxy平面上に表示される「変換座標」V’(x’y’)を求めよ。
 
〇解答
式④より、「変換座標」V’=「実座標」V×「変換行列」Mである事から、「実座標」Vと「変換行列」Mが分かれば「変換座標」V’を求められる。
「実座標」Vxyzは既知である。
 計算の目的が座標計算である事からω=1(方向は0)となる。
「変換行列」Mは、問題文より「Y軸を中心に回転」させたいので、⑶「Y軸中心の回転」に示した「変換行列」を用いる。
以上で計算に必要な材料は揃ったので、これを計算したものを式⑤に示す。
イメージ 6
 
問題文より、欲しい計算値はx’y’だけで良い事からz’ωは省略できる。
また式⑤より「実座標y=変換座標y’」である事からY軸については計算せずとも式⑥の通りyの値をそのまま使える。イメージ 7
 
以上の結果より、三次元空間に有る点V(xyz)Y軸を中心にθ°回転させ、その結果をディスプレイ上に表示する為には、「変換座標」x’だけ求めればよい事になる。
式⑤より、「変換座標」x’は式⑦の通り「実座標」x,zによって表す事が出来る。
実際には基準となる原点O(Ox,Oy,Oz)の値が全てゼロとは限らない事から、x,zから一度原点の値Ox,Ozを引いてから座標変換し、最後に原点の値Ox,Ozを足し戻すという操作を加える。
原点の値Ox,Ozを考慮すると式⑧の様になる。イメージ 8イメージ 9

4. 応用

 式⑧EXCELVBAにそのまま組み込める様に関数化したものを表3の通り作ってみました
 ついでに変換行列(1)(2)(4)についても同様に表1,2,4の通り作りました。
 
表1:(1)「平行移動」のVBA用関数
’X座標
Function MovX(x As Variant, Ox As Variant, tx As Variant) As Variant
    MovX = x + tx - Ox
End Function

'Y座標
Function MovY(y As Variant, Oy As Variant, ty As Variant) As Variant
    MovY = y + ty - Oy
End Function
 
表2:(2)「X軸を中心にθ°回転」のVBA用関数
’X座標:「x'=x」なので変換の必要なし
 
'Y座標
Function XRotY(y As Variant, z As Variant, Oy As Variant, Oz As Variant, _
 θ As Variant) As Variant
    XRotY = Cos((PI / 180) * θ) * (y - Oy) - Sin((PI / 180) * θ) * (z - Oz) + Oy
End Function
 
表3:(3)「Y軸を中心にθ°回転」のVBA用関数
'X座標
Function YRotX(x As Variant, z As Variant, Ox As Variant, Oz As Variant, _
 θ As Variant) As Variant
    YRotX = Cos((PI / 180) * θ) * (x - Ox) + Sin((PI / 180) * θ) * (z - Oz) + Ox
End Function
 
’Y座標:「y'=y」なので変換の必要なし
 
表4:(4)「Z軸を中心にθ°回転」のVBA用関数
’X座標
Function ZRotX(x As Variant, y As Variant, Ox As Variant, Oy As Variant, _
θ As Variant) As Variant
    ZRotX = Cos((PI / 180) * θ) * (x - Ox) - Sin((PI / 180) * θ) * (y - Oy) + Ox
End Function

'Y座標
Function ZRotY(x As Variant, y As Variant, Ox As Variant, Oy As Variant, _
θ As Variant) As Variant
    ZRotY = Sin((PI / 180) * θ) * (x - Ox) + Cos((PI / 180) * θ) * (y - Oy) + Oy
End Function

5. まとめ

 これでアフィン変換により3Dオブジェクトを自由に動かせる準備が整いました 
 取り敢えず表3の「Y軸を中心にθ°回転」する作ったVBA関数を使って、4脚で歩く平面のストランドビーストを東京モーターショウで展示されている車の様にクルクル回してみ様かと思います!
 
イメージ 1 イメージ 3
励みになりますのでよければクリック下さい(^o^)/

↩【NOBのArduino日記!】目次に戻る