スライド資料

3次元座標変換の特徴
OpenGLでは3つの座標変換行列
(2次元座標変換になかったもの)
モデリング座標系
モデリング
変換
Y
ワールド座標系
視野変換
カメラ座標系
投影変換
y
• 任意方向軸まわりの回転変換
x
基準座標系
0
ビューポート
– 位置と大きさと、回転軸方向も変化する
変換
• 3次元座標系変換
デバイス座標系
でビューイングパイプライン(物体の定義から表示までの一連の処理)構成
視点
– 基本回転軸方向が3つある回転変換を利用
– 投影変換の一種、非線形変換
y
x
z
y
x
X
glViewport(0,0,w,h)
• 透視変換
z
Z
glMatrixMode(GL_PROJECTION)
glMatrixMode(GL_MODELVIEW)
これ以降宣言される変換行列は、投影
変換用行列に右から掛けられる
これ以降宣言される変換行列は、モデリ
ング変換用行列に右から掛けられる
1
2
3次元座標系の変換
2次元から拡張した座標変換行列
• ワールド座標系oxyz,ローカルo'uvwを考える
– Pはoxyz座標系での座標値は(x,y,z)
– o'uvw座標系での座標値は(u,v,w)
y
u
• oxyz座標系からみた、o'uvw系の各
単位軸ベクトル o'u,o'v,o'wの座標値をそれぞれ
(ux,uy,uz),(vx,vy,vz),(wx,wy,wz)とすると
OP = Oo'+u × o' u + v × o' v + w × o' w
æ wx ö
æ rx ö æ u x ö æ v x ö
ç ÷
ç ÷ ç ÷ ç ÷
= ç ry ÷ + uç u y ÷ + vç v y ÷ + wç wy ÷
çw ÷
ç r ÷ çu ÷ çv ÷
è zø
è zø è zø è zø
æ ux
ç
= ç uy
çu
è z
vx
vy
vz
wx öæ u ö æ rx ö
÷ç ÷ ç ÷
wy ÷ç v ÷ + ç ry ÷
wz ÷øçè w ÷ø çè rz ÷ø
w
P
o'

r (rx , ry , rz )
o
v
x
z
平行移動成分
vx
wx
vy
vz
wy
wz
0
0
• 拡大縮小変換
rx ö é u ù
÷
ry ÷ êê v úú
rz ÷ ê wú
÷ê ú
1 ÷ø ë 1 û
回転・拡大縮小成分
éu ù æ 1
êv ú ç0
ê ú=ç
ê wú ç 0
ê ú çç
ë1û è0
• z軸回りの回転変換
– z軸中心
同次座標系で表現すると
é xù æ ux
ê yú ç u
ê ú=ç y
ê z ú ç uz
ê ú çç
ë1 û è 0
• 平行移動変換
– 原点中心
0 0 a öé x ù
÷
1 0 b ÷ êê y úú
0 1 c ÷ê z ú
÷ê ú
0 0 1 ÷ø ë 1 û
æ cos g
ç
ç sin g
ç 0
ç
ç 0
è
æ s 0 0 0ö
ç
÷
ç 0 t 0 0÷
ç 0 0 u 0÷
ç
÷
ç 0 0 0 1÷
è
ø
- sin g
cos g
0
0
0 0ö
÷
0 0÷
1 0÷
÷
0 1 ÷ø
y
Q( X , Y )
P( x, y )
x
c
z
y
( X ,Y )
g ( x, y)
0
x
z
y
Q( X , Y )
P( x, y )
u
z
3
b
a
0
1
0
1
1
t
x
s
4
1
3次元直交座標軸回りの回転変換
• 軸を巡回的に変えると各軸周りの回転が記述できる
y
( X ,Y )
y
q ( x, y )
0
0
2次元表 現
z
次元表現
z軸まわりの回転
æ X ö æ cos q
ç ÷ ç
ç Y ÷ = ç sin q
çZ÷ ç 0
è ø è
- sin q
cosq
0
- sin q öæ y ö
÷ç ÷
cosq ÷øçè z ÷ø
x軸まわりの回転
0 öæ x ö
÷ç ÷
0 ÷ç y ÷
1 ÷øçè z ÷ø
z
0
æ X ö æ1
ç ÷ ç
ç Y ÷ = ç 0 cosq
ç Z ÷ ç 0 sin q
è ø è
0 öæ x ö
÷ç ÷
- sin q ÷ç y ÷
cosq ÷øçè z ÷ø
- sin q öæ z ö
÷ç ÷
cosq ÷øçè x ÷ø
y軸まわりの回転
æ X ö æ cosq
ç ÷ ç
çY ÷=ç 0
ç Z ÷ ç - sin q
è ø è
0 sin q öæ x ö
÷ç ÷
1
0 ÷ç y ÷
0 cos q ÷øçè z ÷ø
5
任意軸周りの回転変換 (2/2)
成分毎に展開すると次式となる
Q
r

ただし n = (nx , ny , nz ) とする
}
R
2
n y (1 - cos q ) + cos q
n y nz (1 - cosq ) + n x sin q
cos q : 1 - cos q
{
}
Y = { nx n y (1 - cos q ) + nz sin q } x + n y (1 - cos q ) + cosq y + { n y nz (1 - cos q ) - nx sin q } z
2
{
}
Z = { n x n z (1 - cosq ) - n z sin q } x + { n y n z (1 - cosq ) + nx sin q } y + nz (1 - cosq ) + cosq z
2
n x n z (1 - cos q ) + n y sin q öæ x ö
÷ç ÷
n y nz (1 - cosq ) - nx sin q ÷ç y ÷
÷
2
nz (1 - cosq ) + cos q ÷øçè z ÷ø
Q(a’,b’,c’)
n y n z (1 - cosq ) + n x sin q
æuö
æ u ö æaö
è è ø è ø è ø øç w ÷
è ø
ç w÷ ç c ÷
è ø è ø
7




 æ æ  ö æ m ö æ n ö öç ÷ ç ÷ ç ÷
OP = u  + vm + w n = çç çç ÷÷ çç ÷÷ çç ÷÷ ÷÷ç v ÷ = Rç v ÷ = ç b ÷


ただし、 |  |=| m |=| n |= 1
n x n z (1 - cosq ) + n y sin q ö
÷
n y nz (1 - cosq ) - n x sin q ÷
÷
2
n z (1 - cosq ) + cosq ÷ø
y
O-lmn座標系からO-xyz座標系への回転変換行列をRとする

nx n y (1 - cosq ) - n z sin q
2
n y (1 - cosq ) + cos q
6
R
O-lmn座標系での座標値P(u,v,w), Q(u',v',w')

したがって、n = ( nx , n y , nz ) 軸まわりの回転変換行列は次の通り
æ nx 2 (1 - cosq ) + cosq
ç
ç nx n y (1 - cos q ) + n z sin q
çç
è n x nz (1 - cosq ) - n y sin q
P
任意軸周りの回転変換の別解
成分毎に展開した式をベクトルと行列で表現すると次式となる。
n x n y (1 - cosq ) - nz sin q
θ
H
X = n x (1 - cos q ) + cosq x + { nx n y (1 - cosq ) - nz sin q } y + { nx n z (1 - cosq ) + n y sin q } z
2
O-xyz座標系での座標値P(a,b,c), Q(a',b',c')
2
æ X ö æç n x (1 - cos q ) + cos q
ç ÷
ç
Y
=
n
n
ç ÷
x y (1 - cosq ) + n z sin q
ç Z ÷ çç n n (1 - cos q ) - n sin q
y
è ø è x z
x
æ ny z - nz y ö
æXö
æ nx ö
æxö
ç
÷
ç ÷
ç ÷
ç ÷
ç Y ÷ = ( x × n x + y × n y + z × n z )(1 - cos q )ç n y ÷ + cosq × ç y ÷ + sin q × ç n z x - n x z ÷
ç
÷
çZ÷
çn ÷
çz÷
è ø
è zø
è ø
è nx y - ny x ø
{
P
a
o
z
θ
H
n
 

OQ = (OP × n ) n (1 - cos q ) + cos q OP + n ´ OP sin q
æ Z ö æ cos q
çç X ÷÷ = çç sin q
è ø è
Q
R
y
OH = (1 - cos q )OR + cos q × OP
 
OR = (OP × n )n
y
æ Y ö æ cosq
çç Z ÷÷ = çç sin q
è ø è
- sin q öæ x ö
÷ç ÷
cos q ÷øçè y ÷ø
0
y
x
æ X ö æ cos q
çç ÷÷ = çç
è Y ø è sin q
3
q ( z , x)
q ( y, z )
x

n ´ OP

HQ = r sin q 
= (n ´ OP) sin q
| n ´ OP |
(Z , X )
(Y , Z )
z
r
1


| n ´ OP | =| n | × | OP | sin a = r
OQ = OH + HQ
x
z
x
任意軸周りの回転変換 (1/2)
z
θ
P(a,b,c)
n
o 
x
m
æ u ' ö æ a' ö

ç ÷ ç ÷


OQ = u '  + v ' m + w' n = Rç v' ÷ = ç b ' ÷ と表現できる
æ u' ö æ cosq - sin q 0 öæ u ö
æuö
ç w'÷ ç c ' ÷ また、O-lmn系では çç v' ÷÷ = çç sin q cosq 0 ÷÷çç v ÷÷ = Cq çç v ÷÷
è ø è ø
ç w' ÷ ç 0
÷
ç
÷
ç w÷
0
1 øè w ø
è ø è
è ø
このとき、次式の関係が成り立つ
が成り立つ
æ a' ö
æ u' ö
æuö
æaö
æ æ ö æ ö æ öö
ç ÷
ç ÷
ç ÷
ç ÷
æ cos q - sin q 0 ö
-1
ç 
÷
ç b' ÷ = Rç v' ÷ = RCq ç v ÷ = RCq R ç b ÷ ただし Cq = çç sin q cosq 0 ÷÷ R = ç çç  ÷÷ çç m ÷÷ çç n ÷÷ ÷
ç c' ÷
ç w' ÷
ç w÷
çc÷
ç 0
÷
ç
÷
ç
÷
ç
÷
ç
÷
0
1ø
è ø
è ø
è ø
è ø
è
è è ø è ø è øø
よって R × Cq × R -1 がO-xyz系でみたn軸回りの回転変換行列である
8
2
透視変換について(2/3)
透視変換について(1/3)
正規化
ビューボリューム
( x, y , z )
( x1 , y1 ,1)
後方クリッピング面
前方クリッピング面
y
投影面
視点
z
z
(左手座標系) min
z
x
(右手座標系)
上から見た図
zmin
視点
z
0
(左手座標系)
zmax
1
x
0
1
x
~z
min
x
z
(左手座標系)
2
ここで、
~
z min
1
z
= min
z max
9
透視変換について(3/3)
結局、
正規化ビューボリュームからの
透視投影では、
x' =
y' =
x
z
( x, y, z )
0
2
~z
min
y
z
1
~
1
z min 1
z' =
×
~
1 - zmin 1 - ~z min z
0
1
0
0
1
1 - ~zmin
0
1
0
z
1
zに関しては
z : z min ® 1
z
z1 =
更に、x,yと同様にzで割って
の変化のとき、
z' =
透視投影後の範囲は
z1 : 0 ® 1
z-~
z min
1- ~
z min
となる
~z
z1 z - ~zmin 1
1
1
=
× =
- min
×
~
~
z 1 - zmin z 1 - z min 1 - ~
zmin z
z
z min = min
但し、 ~
z max
10
x' =
上方向ベクトル
注視点
• gluPerspective
top
left
(fov, aspect, near, far)
視野角 縦横比 前方 後方クリッピング面
を計算した後、
0
-~
z min
1- ~
zmin
0
y1 = y ' =
x
このようなzの変動範囲の変換式は
– 視線方向が中心位置でなくても良い
z
x
öé x ù
÷
÷ê y ú
÷ê ú
÷ê z ú
÷ êë 1 úû
ø
x : z = x1 : 1 より
x
x1 = x' =
z
y
1
1
x
0
透視面
• glFrustum(left, right, bottom, top, near, far)
( x' , y' , z ' )
0
z
1
0
透視変換を行う関数
透視投影
1
これは線形変換でない。そこで、
é x" ù æç 1
ê y"ú ç 0
ê ú=ç
ê z" ú ç 0
ê ú ç
ë w"û è 0
-1
( x1 , y1 ,1)
( x ' , y ' , z' )
透視投影
1
透視投影では、
同様に
z
2
~
zmin
正規化
ビューボリューム
正規化
視点
視点
ビューボリューム
この四角錐 台の内部に
在する物 体のみ表示
zmax 存
される
-1
x"
y"
z"
, y' =
, z' =
w"
w"
w"
により最終変換結果を得る
11
right
bottom
視点
視野角
near
far
• gluLookAt( ex,ey,ez, cx,cy,cz, ux,uy,uz)
視点
注視点
上方向ベクトル
【参考】平行透視(正射影)を行う関数
glOrtho(xmin,xmax,ymin,ymax,zmin,zmax)
12
3
2D→3Dへ逆変換を行う関数
投影法の体系
(JIS8114-1984より)
• 対話操作に重要
– スクリーンから3次元空間へ
• glGetintegerv( )
スクリーン
– viewport変換行列を取得
• glGetDoublev( )
視点
near
far
– モデリング視野変換行列、投影変換行列を取得
• gluUnProject( )
立体図
single view
drawing
– 3つの変換行列と2次元スクリーン座標値を与えて
3次元空間内の直線に変換して、物体との交点か
ら3次元座標値を得る
中心投影
central
13
3次元の回転、平行移動の操作部
プログラミングの説明
14
y
正四面体の組み立て(1/7)
図形の表示と折り曲げを別々に行う場合
D2
x
D
0
1
D=
3
= 0.2887 .....
6
D2 = 2 * D =
①手前に折り曲げる
3
= 0 .5774 ....
3
③手前に折り曲げる
一辺の長さ
固定面
座標変換行列
æX ö
æ xö
ç ÷
ç ÷
çY ÷
ç y÷
=
M
çZ÷
çz÷
ç ÷
ç ÷
ç1÷
ç1÷
è ø
è ø
15
②
図形が定義された座標系
での座標値
①
②手前に折り曲げる
図形を表示するワールド
座標系での座標値
glCallList( TRIANGLE );
③
16
4
正四面体の組み立て(2/7)
y
図形のコピー
D2
正四面体の組み立て(3/7)
y
コピーした図形の回転(原点回り)
D2
x
x
D
0
D
回転角(度)
回転軸ベクトル
glCallList( TRIANGLE );
glCallList( TRIANGLE );
glCallList( TRIANGLE );
変換行列
æX ö
æ xö
ç ÷
ç ÷
çY ÷
ç y÷
M
=
çZ÷
çz÷
ç ÷
ç ÷
ç1÷
ç1÷
è ø
è ø
180度の回転
(z軸まわり)
ワールド座標
系での三角形
の各頂点座標
【注】縁取りした記述が、
縁取りした図形を示す
図形を表示するワールド
座標系での座標値
0
z軸まわりの回転変換行列
æX ö
æ xö
ç ÷
ç ÷
çY ÷
ç y÷
R
=
(
180
)
z
çZ÷
çz÷
ç ÷
ç ÷
ç1÷
ç1÷
è ø
è ø
図形が定義された座標系
での座標値
glRotatef( 180.,0.,0.,1. );
glCallList( TRIANGLE );
物体座標系での
三角形の各頂点座標
17
正四面体の組み立て(4/7)
y
y
図形の移動(展開図表示のため)
D2
D
0.5
正四面体の組み立て(5/7)
図形の移動(折り曲げ準備)
D2
Dx
0
18
x
D
移動量ベクトル
(0.5, D, 0)
0
移動量
(0,ーD2,0)
glCallList( TRIANGLE );
平行移動行列
を表示するための箇所
glCallList( TRIANGLE );
glTranslatef( 0.,-D2,0. );
glTranslatef( 0.5,D,0. );
glRotatef( 180.,0.,0.,1. );
glCallList( TRIANGLE );
glTranslatef( 0.5,D,0. );
glRotatef( 180.,0.,0.,1. );
glCallList( TRIANGLE );
æX ö
æ xö
ç ÷
ç ÷
çY ÷
ç y÷
ç Z ÷ = T (0.5, D ,0) × Rz (180 )ç z ÷
ç ÷
ç ÷
ç1÷
ç1÷
è ø
è ø
19
æX ö
æxö
ç ÷
ç ÷
çY ÷
ç y÷
ç Z ÷ = T (0,- D 2,0 ) × T ( 0.5, D,0 ) × Rz (180)ç z ÷
ç ÷
ç ÷
ç1÷
ç1÷
è ø
è ø
20
5
正四面体の組み立て(6/7)
y
図形の回転(折り曲げ)
D2
x
D
y
0
正四面体の組み立て(7/7)
図形の平行移動(元の位置に戻す)
D2
x
回転軸は必ず原点を通る
位置で回転させる
D
0
移動量(0,D2,0)
glCallList( TRIANGLE );
回転角:t
D1 + D 2 =
回転軸ベクトル
(0.5, D1+D2, 0)
glRotatef(t,0.5,D1+D2,0);
glTranslatef( 0.,-D2,0. );
glTranslatef( 0.5,D,0. );
glRotatef( 180.,0.,0.,1. );
glCallList( TRIANGLE );
3
= 0.866....
2
折り曲げ
æX ö
æ xö
ç ÷
ç ÷
çY ÷
ç y÷
θ
R
D
D
T
D
T
D
Rz
=
(
,
0
.
5
,
1
+
2
,
0
)
×
(
0
,
2
,
0
)
×
(
0
.
5
,
,
0
)
×
(
180
)
çZ÷
çz÷
ç ÷
ç ÷
ç1÷
ç1÷
è ø
è ø
21
サンプルプログラム1の方 法
折り曲げ
平行移動 平行移動
回転
(展開形状表示)
平行移動
(折曲形状表示)
サンプル2のプログラム
原点位置
折り曲げ
平行移動
回転
回転
②回転軸まわりに回転
①回転軸が原点を通るように移動
折り曲げ部全体
glCallList( TRIANGLE );
glTranslatef( 0., D2,0. );
glRotatef(t,0.5,-0.866,0);
glTranslatef( 0.,-D2,0. );
glTranslatef( 0.5,D,0. );
glRotatef( 180.,0.,0.,1. );
glCallList( TRIANGLE );
表示部
æX ö
æ xö
ç ÷
ç ÷
çY ÷
ç y÷
ç Z ÷ = T (0, D 2,0) × R (θ,0.5,- D 2,0) × T ( 0,- D 2,0) × T (0.5, D,0) × Rz (180)ç z ÷
①
②
③
ç ÷
ç ÷
ç1÷
ç1÷
è ø
è ø
22
3次元座標変換の課題
複数の手順がある
回転
③移動した分を元に戻す
1. 正四面体(テトラパック)のサン
プルプログラムを参考に、立方
体の展開図の元プログラムに
折り曲げる操作を挿入して立
方体を組み立てる
2. 他の展開図(右図)から組み立
てる
3. 正十二面体を組み立てる
展開図は右の通り(他のパターンでも良い)
平行移動
折り曲げ角度は63.435度までとする
(折曲形状表示)
23
24
6