座標変換 †
座標変換には大きく分けて以下の4つの種類があります。
モデリング変換
ビュー変換
プロジェクション変換
ビューポート変換
座標と変換の関係は以下のようになります。
ローカル座標
↓ モデリング変換
ワールド座標
↓ ビュー変換
ビュー座標
↓ プロジェクション変換
プロジェクション座標
↓ ビューポート変換
スクリーン座標
) モデリング変換
ボディ座標系からワールド座標系に変換することをモデリング変換といいます。
モデリング変換には、平行移動や回転移動、拡大・縮小のアフィン変換を使います。
考え易いように2次元でモデリング変換を考えてみます。
x
y
θ
To (Tx ,Ty )
p(x,y)
p'(x',y')
x'
y'
/* Origin */
/* Point */
/* Angle */
/* X axis */
/* Y axis */
/* Angle */
/* X axis */
/* Y axis */
/* X axis */
/* Y axis */
上図のようにワールド座標系をx-y、ボディ座標系をx'-y'とします。ワールド座標系からのボディ座標系までをたどってみると、まずθだけ座標を傾け、T0 (Tx ,Ty )まで座標を移動するとワールド座標系からボディ座標系になります。つまりワールド座標系からボディ座標系へ変換する方法により、ボディ座標系でp(x,y)であったものが、ワールド座標系での点の値p'(x',y')が求まります。ここで注意が必要なのはp(x,y)がボディ座標系での点の値であり、p'(x',y')がワールド座標系での点の値ということです。このように考えることにより前述のアフィン変換が利用でき、R を回転移動、T を平行移動の行列とすると以下のようになります。
p ' = TRp
アフィン変換での移動はワールド座標系の原点に対して移動です。したがって回転の移動は初めにワールド座標系の原点に対して変換しておく必要があります。T とR の順番を変えることはできません。各要素を入れて計算すると視点からの座標は以下のようになります。
x' 1 0 Tx cosθ -sinθ 0 x
y' = 0 1 Ty sinθ cosθ 0 y
1 0 0 1 0 0 1 1
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
cosθ -sinθ Tx x
= sinθ cosθ Ty y
0 0 1 1
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
) ビュー変換
図形のワールド座標系の座標を視点(view point)からの座標に変換することをビュー変換といいます。
ビュー変換の方法は視点そのものを移動させる方法と、図形を回転させる方法の2つの考え方があります。
どちらも図形と視点の間の適当な位置に視点からの見える形状を表示する投影面を置きます。
以下の説明で出てくる点について次のように定義しておきます。
p(x,y,z) : ワールド座標系での座標
p'(x',y',z') : 視点(座標)から見た座標。点としてはpと同じですが座標の値が異なります。
p"(x",y",z") : 点pを座標の移動と同じように移動した場合の移動後の座標系での仮想の点。座標の値x",y",z"はpのx,y,zと同じで x"=x, y"=y, z"=zです。
座標の移動
各ビュー変換を考える前に、座標の移動(視点座標)とアフィン変換の関係を説明します。
座標を移動することは図形の座標変換により図形を変形することと異なり、視点から元の図形の位置を計算することで、以下に説明するように座標変換の逆になります。
ここでは分かりやすいように2次元での座標の移動で説明します。
スケール変換
座標が変換行列S 倍になった場合、点p"もp'をS 倍にすれば求まります。
Sp ' = p "
従って視点から見たp 'の座標は以下となります。スケール変換の場合、軸の倍数が変わるだけで図では軸の位置が変わらないので分かりにくいので注意して下さい。
p ' = S ⁻¹p "
ここでp"とpの値は同じなので、結局p'は以下の変換で求められます。
p ' = S ⁻¹p
ビュー変換では、ワールド座標系と視点の座標系が向き合っている場合にy軸の反転(右手座標系の場合左手座標系に変わる)などで使用します。
x
y
x'
y'
p(x,y)
p'(x',y')
p"(x",y")
/* X' axis */
/* Y' axis */
/* X axis */
/* Y axis */
平行移動
座標がx'-y'(Tx,Ty)に平行移動した場合の変換行列をT とする時、点p"もp'からT 平行移動すれば求まります。
Tp ' = p "
従って視点から見たp 'の座標は以下となります。
p ' = T ⁻¹p "
ここでp"とpの値は同じなので、結局p'は以下の変換で求められます。
p ' = T ⁻¹p
x
y
x'
y'
Vo (Tx,Ty)
p(x,y)
p'(x',y')
p"(x",y")
/* X axis */
/* Y axis */
/* X' axis */
/* Y' axis */
/* Origin */
/* Point */
回転移動
座標がx'-y'に回転移動した場合の変換行列をR とする時、点p"もp'からR 回転移動すれば求まります。
Rp ' = p "
従って視点から見たp 'の座標は以下となります。
p ' = R ⁻¹p "
ここでp"とpの値は同じなので、結局p'は以下の変換で求められます。
p ' = R ⁻¹p
x
y
x'
y'
p(x,y)
p'(x',y')
p"(x",y")
θ
/* X axis */
/* Y axis */
/* X' axis */
/* Y' axis */
/* Angle-O */
/* Angle-P */
視点移動(2次元の場合)
視点を移動した場合の視点への座標変換はモデリング変換と似ています。点p'から点p"までの変換をたどってみましょう。
x
y
x'
y'
x"
y"
x"
y"
Vo (Tx,Ty)
p(x,y)
p'(x',y')
θ
/* X axis */
/* Y axis */
/* Origin */
/* X axis */
/* Y axis */
/* X axis */
/* Y axis */
/* Angle */
/* X axis */
/* Y axis */
まず視点座標系をVo (Tx,Ty)まで平行移動(T ⁻¹)します。次にワールド座標系と視点座標系のx軸とx'軸の向きが反対なので反転(S ⁻¹)させます。この結果視点座標系は左手座標系になります。最後にx'軸がワールド座標系の原点を通るようにθ回転(R ⁻¹)させます。この時左手座標系なので時計回り方向が正です。これで視点座標系の点p"がp'まで移動できました。ここで注意が必要なのは上記で説明した各座標変換の逆変換を座標移動後に適用することで連続して各変換をすることができることです。この時の変換式は以下のようになります。
p ' = R ⁻¹S ⁻¹T ⁻¹p "
ここでp "とp の値は同じなので、
p ' = R ⁻¹S ⁻¹T ⁻¹p
となります。各要素を入れて計算すると視点からの座標は以下のようになります。
x' cosθ -sinθ 0 ⁻¹ -1 0 0 ⁻¹ 1 0 Tx ⁻¹ x
y' = sinθ cosθ 0 0 1 0 0 1 Ty y
1 0 0 1 0 0 1 0 0 1 1
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
cosθ sinθ 0 -1 0 0 1 0 -Tx .x
= -sinθ cosθ 0 0 1 0 0 1 -Ty y
0 0 1 0 0 1 0 0 1 1
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
cosθ sinθ 0 -1 0 Tx x
= -sinθ cosθ 0 0 1 -Ty y
0 0 1 0 0 1 1
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
cosθ sinθ Tx cosθ-Ty sinθ x
= -sinθ cosθ -Tx sinθ-Ty cosθ y
0 0 1 1
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
x = -xcosθ + ysinθ + Tx cosθ-Ty sinθ
y = xsinθ + ycosθ - Tx sinθ-Ty cosθ
ここで図形の原点から視点までの距離をrとすると、
Tx = r |cosθ|
Ty = r |sinθ|
またθの値が負の場合、(通常視点から図形を見る時は0°~-90°の範囲で見下ろすことになるので、θの値が負になります。)
sinθ = -|sinθ|
で、これを上記に代入すると
x = -xcosθ + ysinθ + r |cosθ| cosθ+r |sinθ||sinθ|
= -xcosθ + ysinθ + r(cos²θ + sin²θ)
= -xcosθ + ysinθ + r
y = xsinθ + ycosθ + r |cosθ||sinθ|-r |sinθ| cosθ
= xsinθ + ycosθ
視点を移動する場合y軸方向に平行に上下するのではなく、図形の原点を中心として回転することにより図形を真上から見下ろした表示を得ることができます。
図形回転(2次元の場合)
図形を回転させる場合は下図のように視点をワールド座標の原点からTx離した位置の置きます。
x
y
x"
y"
x"
y"
x'
y'
Vo (Tx,Ty)
p(x,y)
p"(x",y")
p'(x',y')
θ
/* X axis */
/* Y axis */
/* Angle */
/* Angle */
/* X axis */
/* Y axis */
/* X axis */
/* Y axis */
/* X axis */
まず図形をワールド座標系でθだけ回転(R )すると点pが点p"まで移動します。ワールド座標は右手座標系なので反時計回りの回転が正となります。次に座標系の移動です。視点Vo (Tx,0)まで座標を平行移動(T ⁻¹)します。最後にx軸を反転します。このスケール変換をS ⁻¹とします。これで視点座標系の点p"がp'まで移動できました。この時の変換式は以下のようになります。
p " = Rp
p ' = S ⁻¹T ⁻¹p "
ここでp " = Rp なので、
p ' = S ⁻¹T ⁻¹Rp
となります。各要素を入れて計算すると視点からの座標は以下のようになります。
x' -1 0 0 ⁻¹ 1 0 Tx ⁻¹ cosθ -sinθ 0 x
y' = 0 1 0 0 1 Ty sinθ cosθ 0 y
1 0 0 1 0 0 1 0 0 1 1
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
-1 0 0 1 0 -Tx cosθ -sinθ. 0 x
= 0 1 0 0 1 -Ty sinθ cosθ 0 y
0 0 1 0 0 1 0 0 1 1
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
-1 0 Tx cosθ -sinθ 0 x
= 0 1 -Ty sinθ cosθ 0 y
0 0 1 0 0 1 1
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
-cosθ sinθ Tx x
= sinθ cosθ -Tx y
0 0 1 1
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
x = -xcosθ + ysinθ + Tx
y = xsinθ + ycosθ - Ty
またTy= 0なので、
y = xsinθ + ycosθ
となります。
ここでTxは図形の原点から視点までの距離なのでこれをrとすると上記のxとyを計算する式は視点移動の式と同じになります。これは当然のことですが、視点移動と図形回転の考え方が異なっても結果は同じということになります。
図形回転(3次元の場合)
次に3次元の場合の図形回転について説明します。水平方向の回転が加わるだけで基本的に2次元の場合と同じです。
視点をワールド座標のy軸上の点Vo (Tx,Ty,Tz)の位置に置きます。ただしここでTxとTzの値は0です。
下図の場合原点から距離をrとするとTyの値は-rになります。
ViewBox内をクリックすると、各変換が順番に表示されます。
x
y
z
Vo (Tx,Ty,Tz) = (0,-r,0)
p(x,y)
/* X axis */
/* Y axis */
/* Z axis */
/* Bottom */
/* Point */
/* View */
/* X axis */
/* Y axis */
/* Z axis */
/* Bottom */
/* Point */
/* Angle */
θz
pª(xª,yª)
xª
yª
zª
/* hidden */
/* X axis */
/* Y axis */
/* Z axis */
/* Bottom */
/* Point */
/* Angle */
θx
p"(x",y")
x"
y"
z"
/* hidden */
p'(x',y')
/* hidden */
/* X axis */
/* Y axis */
/* Z axis */
x'
y'
z'
まず図形をワールド座標系のz軸に対してでθz回転(Rz )すると点pが点pªまで移動します。次にx軸に対してθx回転(Rx )すると点pが点p"まで移動します。ワールド座標は右手座標系なので反時計回りの回転が正となります。次に座標系の移動です。視点Vo (0,r,0)まで平行移動(T ⁻¹)します。この図の場合x軸とy軸の方向が視点座標と同じなので、軸の反転はありません。これで視点座標系の点p"がp'まで移動できました。この時の変換式は以下のようになります。
p " = RxRzp
p ' = T ⁻¹p "
ここでp " = RxRzp なので、
p ' = T ⁻¹RxRzp
となります。各要素を入れて計算すると視点からの座標は以下のようになります。
x' 1 0 0 0 ⁻¹ 1 0 0 0 cosθz -sinθz 0 0 x
y' 0 1 0 Ty 0 cosθx -sinθx 0 sinθz cosθz 0 0 y
z' 0 0 1 0 0 sinθx cosθx 0 0 0 1 0 z
1 . 0 0 0 1 0 0 0 1 0 0 0 1 1
=
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
1 0 0 0 1 0 0 0 cosθz -sinθz 0 0 x
0 1 0 -Ty 0 cosθx -sinθx 0 sinθz cosθz 0 0 y
0 0 1 0 . 0 sinθx cosθx 0 0 0 1 0 z
0 0 0 1 . 0 0 0 1 0 0 0 1 1
=
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
1 0 0 0 cosθz -sinθz 0 0 x
0 1 0 -Ty cosθx sinθz cosθx cosθz -sinθx 0 y
0 0 1 0 sinθx sinθz sinθx cosθz cosθx 0 z
0 0 0 1 0 0 0 1 1
=
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
cosθz -sinθz 0 0 x
cosθx sinθz cosθx cosθz -sinθx -Ty y
sinθx sinθz sinθx cosθz cosθx 0 z
0 0 0 1 1
=
/* Blacket A */
/* Blacket B */
/* Blacket A */
/* Blacket B */
x' = x cosθz - y sinθz
y' = x cosθx sinθz + y cosθx cosθz - z sinθx - Ty
z' = x sinθx sinθz + y sinθx cosθz + z cosθx
となります。
) プロジェクション変換
プロジェクション(投影:Projection)変換とは、3次元空間のデータで計算された図形をモニターなどの2次元平面の上に表示するための変換処理です。
投影の用語
視点:3次元空間上で、立体を見つめる点を視点(view point)といいます。投影中心とも言われます。
投影面:3次元空間の図形を表示する2次元平面のことを投影面といいます。投影面は、投影する図形と視点の間の3次元空間の適当な位置に置かれます。
視線:視点から物体上の各頂点に引かれた線を視線(ray)といいます。透視線とも投射線とも言われます。
透視図:視線が投影面と交差する点によって作成される図形を透視図(perspective)といいます。
代表的な投影法として、平行投影、透視投影があります。平行投影とは、図形から投影面・視点への視線を平行にしたときの投影方法です。透視投影とは、視点から図形への視線が放射状に広がってゆく投影方法です。
平行投影
投影線(視線)が投影面に垂直なものを直投影、そうでないものを斜投影といいます。
透視投影(perspective)
透視投影は、投影面から有限の距離に視点を置いた投影法で、遠近法ともいわれます。パースペクティブの略からパースなどともいわれます。
透視図では、視点から遠いものほど小さく描かれます。
奥行きに対して平行な直線は、一点に集中してゆき、この点を消点といいます。
消点の数の違いにより、透視投影法には次の三種類があり、投影される図形の見え方が異なります。
一点透視図法
二点透視図法
三点透視図法
一点透視図法
消点が一つの透視図を一点透視図といいます。
一点透視図法の投射イメージとしては、3次元座標のy軸のはるか彼方に消点を置き、その点から放射状に視線を広げたものです。
二点透視図法
消点が二つの透視図を二点透視図といいます。
これは、3次元座標のx軸とy軸のはるか彼方にそれぞれ消点を置き、各々の点から放射状に視線を広げたものです。
三点透視図法
消点が三つの透視図を三点透視図といいます。
これは、3次元座標のx軸、y軸とz軸のはるか彼方にそれぞれ消点を置き、各々の点から放射状に視線を広げたものです。
) ビューポート変換
先ほどのプロジェクション変換によって3次元の図形を2次元にすることができました。ビューポート変換とはその2次元で描かれた図形をモニター上に表示するために変換することです。
陰面処理 †
3次元図形を表示させる場合の重要な処理の1つとして、陰面処理(Hidden Surface Elimination)というものがあります。現実世界では図形の裏側の面が見えなかったり、奥の図形が手前の図形の影になって見えなかったりします。このように図形の裏や奥の図形を表示しないようにすることを陰面処理といいます。
陰面処理にも色々な方法がありますが、ここでは代表的なものを紹介します。
) 塗り重ね法
画家が絵を描くとき遠景から順に描いていき、近いものを描く際に以前に描いた遠景の一部を塗りつぶすようにして、遠景の図形を隠すような方法を塗り重ね法といいます。そのためペインタアルゴリズム(painter's algorithm)とも呼ばれます。
このそのまま陰面処理に取り入れたものが塗り重ね法です。
まず描画する面と視点からの距離を計算し、それから視点から離れている面から順番に描画していきます。描画する必要の無い面まで描画するためその分だけ効率が悪くなります。
塗り重ね法ではねじれの関係にある図形や、ある面が別の面を貫通しているような場合はうまくいきません。
) Zバッファ法
Zバッファ法は塗り重ね法に似たアルゴリズムです。 塗り重ね法では各面毎に視点からの距離を計算しましたが、Zバッファ法ではピクセル(点)単位で距離を計算し重なりを判断を計算し描画します。ピクセル単位での計算のため計算量が多くなりますが、計算方法が単純です。
) 法線ベクトル法
法線ベクトル法は、図形の面と視線の関係から法線ベクトルを計算し、その法線の向きから可視面だけを表示する方法です。法線ベクトル法は凸多面体にのみ有効で、凹みがあるような図形や複数の図形が重なるような場合はうまくいきません。
カリング †
図形の裏面や見えない図形を描画しないようにする仕組みをカリング(Culling)と呼びます。
シェーディング †
シェーディング(shading)は、3次元コンピュータグラフィックスやイラストレーションなどで明暗のコントラストで立体感を与える技法です。絵画では陰影画法と呼ばれます。
シェーディングの方法として、ある光源を想定し、その光源の方向と図形の面の傾きから照度を計算し、明暗をつけます。また同じ方向を向いた面でも光源からの距離で光の減衰を与えて、遠近間を表現することもあります。
Last-modified: 2015-12-14 (月) 14:36:33 (3416d)