三次元グラフィック(浮動小数版) [ThreeD]
変換を高速に行うために、変換の内容をあらかじめ数式で計算しておき、
できた変換行列をプログラミングします。
三次元変換は、
- オブジェクト固有のボディ座標系をワールド空間に配置した
ワールド座標系
- さらに視野変換した視点座標系
- さらに変換したクリッピング座標系
- さらに透視変換した透視座標系
- さらにビュー&ウィンドウ変換したスクリーン座標系、
の順番で描画すべき座標を計算します。
プログラムでは、以下のように処理が分かれます。
- オブジェクトごとに、ボディ座標系からワールド座標系へ
- 全ポリゴンを、ワールド座標系からクリッピング座標系へ
- 全ポリゴンを、クリッピング
- 全ポリゴンを、クリッピング座標系からスクリーン座標系へ
クリッピングしない場合(あらかじめ視野に入ったデータを作る場合)は、
以下のように処理が分かれます。
- オブジェクトごとに、ボディ座標系からワールド座標系へ
- 全ポリゴンを、ワールド座標系からスクリーン座標系へ
(x,y,z,w) * T1 * T2 = (X,Y,Z,W)
|
|
*
|
| xX | xY | xZ | xW |
| yX | yY | yZ | yW |
| zX | zY | zZ | zW |
| wX | wY | wZ | wW |
|
=
|
|
- T1, T2 : 以下に示す 4x4 の変換行列, T1 の変換が先に行われる
- x,y,z : 変換前の座標
- X,Y,Z : 変換後の座標
- w,W : 乗数、(X,Y,Z,W) のとき (x,y,z) = (X/W, Y/W, Z/W)
同じ座標系においてある点の座標を変換する場合と、
同じ位置の座標に対して座標系を変換する場合では、
逆変換の関係があります。
(x,y,z,w)の右側に行列をかける場合と、左側にかける場合では、
同じ変換でも行列が異なり、転置(行と列を交換した行列)の
関係があります。
(x,y,z,w) * Move(x,y,z) = (X,Y,Z,W)
X 軸まわり:(x,y,z,w) * RotX(θ) = (X,Y,Z,W)
Y 軸まわり:(x,y,z,w) * RotY(φ) = (X,Y,Z,W)
Z 軸まわり:(x,y,z,w) * RotZ(α) = (X,Y,Z,W)
座標系は右手座標系、
角度は軸に対して右ねじ方向を正とする。
|
|
*
|
| 1 | 0 | 0 | 0 |
| 0 | cos θ | sin θ | 0 |
| 0 | -sin θ | cos θ | 0 |
| 0 | 0 | 0 | 1 |
|
=
|
|
|
|
*
|
| cos φ | 0 | -sin φ | 0 |
| 0 | 1 | 0 | 0 |
| sin φ | 0 | cos φ | 0 |
| 0 | 0 | 0 | 1 |
|
=
|
|
|
|
*
|
| cos α | sin α | 0 | 0 |
| -sin α | cos α | 0 | 0 |
| 0 | 0 | 1 | 0 |
| 0 | 0 | 0 | 1 |
|
=
|
|
sin, cos は、角度から求めなくても、Y成分/斜辺長, X成分/斜辺長
から計算することができます。
Y 軸回転の sin の符号が逆な理由は、
Y 軸から見て Z→X が右ねじ方向なためです。
(X 軸から見たら Y→Z, Z 軸から見たら X→Y が右ねじ方向)
ワールド座標系から視点座標系への変換です。
(x,y,z,w) * View(xf,yf,zf,β,α) = (X,Y,Z,W)
View(xf,yf,zf,β,α) = Move(-xf,-yf,-zf) * RotY(-α) * RotX(-β)
|
|
*
|
| cosα | sinα*sinβ | -sinα*cosβ | 0 |
| 0 | cos β | sin β | 0 |
| sinα | -cosα*sinβ | cosα*cosβ | 0 |
| -xf*cosα-xf*sinα |
-xf*sinα*sinβ-yf*cosβ+zf*cosα*sinβ |
xf*sinα*cosβ-yf*sinβ-zf*cosα*cosβ |
1 |
|
=
|
|
視点座標系から透視座標系への変換です。
(x,y,z,w) * Through(h) = (X,Y,Z,W)
h = xy平面を投影面としたときの視点の Z座標
変換後の透視座標系の値が次の範囲に収まるようにする変換です。
- 投影面の中にある場合、x, y は -1〜 1
- 投影面を z=0, 無限遠を z=1
正規化された x, y は、スクリーン座標系に変換するのが
容易になります。正規化された z は、Z バッファの深さ
(扱える値の範囲)に限らず、投影面から無限遠まで
扱うことができるようになります。
(x,y,z,1) * NThrough(k,h) = (X,Y,Z,W)
k = 正方形の投影面における1辺の長さの半分
h = xy平面を投影面としたときの視点の Z座標
クリッピングの判定を容易にするために、
視点座標系をクリッピング座標系に変換します。
(x,y,z,1) * NClip(k,h) = (X,Y,Z,W)
k = 正方形の投影面における1辺の長さの半分
h = xy平面を投影面としたときの視点の Z座標
クリッピング座標系では、z < x < -z, z < y < -z(z は負)
が真のときに、ピラミッドの側面より内部にあると判定できます。
クリッピングは透視変換する前に行わないと、
Z 値がおかしくなります。
それは、線形補間によってクリッピングされる x,y 座標を
求めたとしても Z 値は線形でないからです。
| 文章名・文献名 | 文章番号 または ISBN 著者 出版者 |
| CAD 工学 |
ISBN4-563-01493-1 山口富士夫著、培風館 |
written by Masanori Toda from Jul.27.1999