図1:「アフィン変換」による3D表示(ディスプレイの座標と物体のイメージ)
図2:「透視投影変換」による3D表示(ディスプレイの座標と物体のイメージ)
先日の記事で作った「ストランドビースト」2次元シミュレートモデル(プログラム)を3次元シミュレートモデルに1次元UPさせたいです!
と言う事で3DCGの基礎から勉強してみました!
1. 3D座標計算とは?
3DCGや3DCADにおいてオブジェクトが移動したり回転したりする際には座標変換が行われています。
代表的な座標変換方式として「アフィン変換」※1や「透視投影変換」※2があります。
以下補足です
※1:「アフィン変換」とは、3DCGや3DCAD等において、モデル座標→ワールド座標→カメラ座標の座標変換を行う際に使用される平行移動と線形変換による座標変換方式の一種。線形変換である事から座標を変換しても線の長さの比は変わりません。(図1参照)
2. アフィン変換!
こちらの詳しい資料を基に一番基本的な3DCG座標変換手法である「アフィン変換」に関する要点だけまとめてみました
2.1 実座標
「実座標」とは、表現しようとするxyzの3軸で構成される3次元空間における点の位置を表します。(式①)
2.2 同次座標
「同次座標」とは、「実座標」xyzにωを加えて点の座標を表すものです。(式②)
ω=1を加える事で座標計算を簡素化出来たり、ω=0を加える事で原点からの方角を計算する事が出来などの利点があります。
2.3 変換行列
「変換行列」とは、「同次座標」に掛け合わせる事で座標を変換(移動・回転・拡大・変形等)する事が出来ます。(式③)
m0~m15の値に回転角度や移動距離等を使用した関数や0や1等を代入する事で、様々な座標変換機能を持たせる事が可能です。
参考に基本的な「平行移動」・「X軸中心の回転」・「Y軸中心の回転」・「Z軸中心の回転」に用いる「変換行列」について⑴~⑷に示します。
2.4 変換座標
「変換座標」V’とは、「同次座標」V(式②)に「変換行列」M(式③)を掛ける事で座標変換された値です。
「変換座標」V’を式で表したものを式④に示します。
3. 例題
今私がやりたい事を自分で例題にして自分で解答してみました
〇例題
「実座標」V(xyz)に有る点を、原点O(Ox,Oy,Oz)から延びるY軸を中心にθ°回転させる。
この時の点V(xyz)がディスプレイのxy平面上に表示される「変換座標」V’(x’y’)を求めよ。
〇解答
式④より、「変換座標」V’=「実座標」V×「変換行列」Mである事から、「実座標」Vと「変換行列」Mが分かれば「変換座標」V’を求められる。
「実座標」Vのxyzは既知である。
計算の目的が座標計算である事からω=1(方向は0)となる。
「変換行列」Mは、問題文より「Y軸を中心に回転」させたいので、⑶「Y軸中心の回転」に示した「変換行列」を用いる。
以上で計算に必要な材料は揃ったので、これを計算したものを式⑤に示す。
問題文より、欲しい計算値はx’y’だけで良い事からz’ω’は省略できる。
また式⑤より「実座標y=変換座標y’」である事からY軸については計算せずとも式⑥の通りyの値をそのまま使える。
以上の結果より、三次元空間に有る点V(xyz)をY軸を中心にθ°回転させ、その結果をディスプレイ上に表示する為には、「変換座標」x’だけ求めればよい事になる。
式⑤より、「変換座標」x’は式⑦の通り「実座標」x,zによって表す事が出来る。
実際には基準となる原点O(Ox,Oy,Oz)の値が全てゼロとは限らない事から、x,zから一度原点の値Ox,Ozを引いてから座標変換し、最後に原点の値Ox,Ozを足し戻すという操作を加える。
原点の値Ox,Ozを考慮すると式⑧の様になる。
4. 応用
ついでに変換行列(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
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
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」なので変換の必要なし
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
表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
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オブジェクトを自由に動かせる準備が整いました
励みになりますのでよければクリック下さい(^o^)/