第5章 CG で使われる変換

第 5 章 CG で使われる変換
第 5 章 CG で使われる変換
畔上 秀幸
名古屋大学 情報科学研究科 複雑系科学専攻
December 15, 2016
1 / 40
第 5 章 CG で使われる変換
はじめに
§5.1 はじめに
(目標) CG で使われる幾何変換,投影変換,視野変換の理論と OpenGL を用
いた変換方法について理解する.
2 / 40
第 5 章 CG で使われる変換
はじめに
§5.2 CG で使われる変換の種類
CG で使われる変換には次の種類がある.
幾何変換 3 次元形状モデルの定義された局所座標系を平行移動,回転移動,
拡大・縮小変形を行う変換(座標変換は幾何変換の逆向き)を幾
何変換 (geometric transformation) という.
⇒ 異なる座標系でモデリングされたパーツを全体座標系で組み
合わせるあるいは分解する際に幾何変換が使われる.
投影変換 3 次元形状モデルをディスプレイや印刷面の 2 次元面に投影する
変換を投影変換 (projective transformation) という.
⇒ モデリングされた形状をディスプレイに表示したり,プリン
タで印刷する際に投影変換が使われる.
視野変換 視点の位置あるいは投影する方向(視線の方向)を移動・回転す
る変換を視野変換 (viewing transformation) という.
⇒ 実際には 3 次元形状モデルを幾何変換することになる.
3 / 40
第 5 章 CG で使われる変換
はじめに
§5.3 幾何変換
平行移動,回転移動,投影変換を行列で表現するために同次座標を用いる.
定義 5.3.1 (同次座標)
T
x = (x1 , x2 , · · · , xn ) に対して
x1 =
y1
,
w
x2 =
y2
,
w
···
, xn =
yn
w
T
が成り立つような y = (y1 , y2 , · · · , yn , w) を x の同次座標 (homogeneous
coordinate) 表現という.
4 / 40
第 5 章 CG で使われる変換
はじめに
§5.3.1 平行移動
T
T
点 x = (x1 , x2 , x3 ) を a = (a1 , a2 , a3 ) だけ平行移動した点
T
′
x = (x′1 , x′2 , x′3 ) は
 ′ 
 
 ′ 

x1
x1
1 0 0 a1
x1
x1 + a1
x′2  0 1 0 a2  x2 
 ′=
 
 ′ 

x3  0 0 1 a3  x3  ∴ x2′ = x2 + a2
x3
x3 + a3
1
1
0 0 0 1
となる.この変換は, y, y ′ を x, x′ の同次座標 (homogeneous coordinate) 表現
とするとき
y ′ = T (a) y
とかける.
5 / 40
第 5 章 CG で使われる変換
はじめに
§5.3.2 回転
T
点 x = (x1 , x2 , x3 ) を x1 軸, x2 軸, x3 軸に対して時計回りに θ1 , θ2 , θ3 だけ
T
回転した点を x′ = (x′1 , x′2 , x′3 ) とするとき
 ′ 
x1
1
0
0
x′2  0 cos θ1 − sin θ1
 ′=
x3  0 sin θ1
cos θ1
1
0
0
0
 ′ 
cos θ2
0 sin θ2
x1
x′2   0
1
0
 ′=
x3  − sin θ2 0 cos θ2
1
0
0
0
 ′ 
x1
cos θ3 − sin θ3 0
x′2   sin θ3
cos θ3
0
 ′ = 
x3   0
0
1
1
0
0
0
 
x1
0
x2 
0
 ,
0 x3 
1
1
 
0
x1
x2 
0
 ,
0 x3 
1
1
 
0
x1
x2 
0
 
0 x3 
1
1
6 / 40
第 5 章 CG で使われる変換
はじめに
となる.この変換を
y ′ = Ri (θi ) y
(i = 1, 2, 3)
とかく.
(注)
( ′)
(
)
(
)
x1
cos(α + θ)
cos α cos θ − sin α sin θ
=
r
=
r
x′2
sin(α + θ)
cos α cos θ + sin α sin θ
(
)( )
x1
cos θ − sin θ
=r
sin θ cos θ
x2
7 / 40
第 5 章 CG で使われる変換
はじめに
x2
x0
x
θ
®
x1
x3
図 5.1: 回転
8 / 40
第 5 章 CG で使われる変換
はじめに
§5.3.3 拡大・縮小
T
点 x = (x1 , x2 , x3 ) を x1
T
x′ = (x′1 , x′2 , x′3 ) は
 ′ 
x1
b1 0 0
x′2   0 b2 0
 ′=
x3   0 0 b3
1
0 0 0
軸, x2 軸, x3 軸 に対して b1 , b2 , b3 倍した点
 
0
x1
x2 
0
 
0 x3 
1
1
T
となる.この変換を,b = (b1 , b2 , b3 ) として
y ′ = S (b) y
とかく.
9 / 40
第 5 章 CG で使われる変換
はじめに
§5.3.4 反転
点 x = (x1 , x2 , x3 )
T
x′ = (x′1 , x′2 , x′3 ) は
 ′ 
−1
x1
x′2   0
 ′=
x3   0
1
0
 ′ 
−1
x1
x′2   0
 ′=
x3   0
0
1
T
を x1 軸,および原点,に対して反転した点


0 0 0
x1


1 0 0
  x2  ,


0 1 0
x3 z 
0 0 1
1
 
0
0 0
x1
 
−1 0 0
 x 2 
0 −1 0 x3 
1
0
0 1
となる.これらの変換は,拡大・縮小の特別な場合とみなせる.
10 / 40
第 5 章 CG で使われる変換
はじめに
§5.3.5 任意の軸回りの回転移動
T
T
点 x = (x1 , x2 , x3 ) を点 x0 = (x01 , x02 , x03 ) を始点とする単位ベクトル
T
T
n = (n1 , n2 , n3 ) に対して時計方向に θ だけ回転した点 x′ = (x′1 , x′2 , x′3 ) への
変換を考えてみよう.
x3
n
x
θ
x
0
x0
x2
x1
図 5.2: 任意の軸回りの回転移動
11 / 40
第 5 章 CG で使われる変換
はじめに
1
点 x0 を原点に平行移動する.
y1 = T (−x0 ) y
2
T
単位ベクトル n = (n1 , n2 , n3 ) を x3 軸回りに α だけ回転して x2 − x3 平
面内に移動する.
y2 = R3 (α) y1 ,
n2
cos α = √ 2
,
n1 + n22
n1
sin α = √ 2
n1 + n22
x3
x3
®
n
x2
x2
x1
図 5.3: 点 x0 を原点に平行移動
x1
図 5.4: n を z 軸回りに α だけ回転
12 / 40
第 5 章 CG で使われる変換
はじめに
3
n1 を x1 軸回りに β だけ回転して x1 軸と一致させる.
y3 = R1 (β) y2 ,
4
cos β = n3
n2 を x3 軸回りに θ だけ回転する.
y4 = R3 (θ) y3
x3
x3
¯
µ
x2
x1
x2
x1
図 5.6: n2 を x3 軸回りに θ だけ回転
図 5.5: n1 を x1 軸回りに β だけ回転
13 / 40
第 5 章 CG で使われる変換
はじめに
5
(3) の逆変換を行う.
y5 = R1−1 (β) y4
6
(2) の逆変換を行う.
y6 = R3−1 (α) y5
7
(1) の逆変換を行う.
y7 = T −1 (−x0 ) y6
したがって,
y7 = T −1 (−x0 ) R3−1 (α) R1−1 (β) R3 (θ) R1 (β) R3 (α) T (−x0 ) y
となる.
14 / 40
第 5 章 CG で使われる変換
はじめに
§5.3.6 Euler 角による回転
T
全体座標系 x1 -x2 -x3 の点 x = (x1 , x2 , x3 ) から局所座標系 xE1 -xE2 -xE3 の
T
点 xE = (xE1 , xE2 , xE3 ) への回転が Euler 角 (α, β, γ) で与えられているとき,
yL = R2 (γ) R1 (β) R3 (α) y
となる.
x3
xE3
xE2
¯
x1
®
x2
°
xE1
x10
図 5.7: Euler 角による回転
15 / 40
第 5 章 CG で使われる変換
はじめに
§5.4 投影変換
定義 5.4.1 (視座標系)
全体座標系 (world coordinate system) x1 -x2 -x3 に対して,視線を xV3 軸とした
xV1 -xV2 -xV3 座標系を視座標系 (viewing coordinate system) という.全体座標系
は右手系,視座標系は,通常,左手系とする.このとき,x1 = xV1 , x2 = xV2
となる.
x2=xV2
x3
xV3
x1=xV1
図 5.8: 視座標系
16 / 40
第 5 章 CG で使われる変換
はじめに
定義 5.4.2 (正規化視座標系)
視座標系の可視領域を正規化した座標系を正規化視座標系 (normalized viewing
coordinate system) という.
この座標系は,第 7 章において,隠面/隠線処理に使われる.
»3
(1,1,1)
»2
({1,{1,0)
»1
図 5.9: 正規化視座標系
17 / 40
第 5 章 CG で使われる変換
はじめに
定義 5.4.3 (透視投影, 平行投影)
投影変換には次の 2 種類がある.
1
2
視点を xV3 軸上に置き,xV3 軸に垂直な面に投影する変換を透視投影
(perspective projection) という.
視点を全体座標系の x3 軸上無限遠方に置き, xV3 軸に垂直な面に投影す
る変換を平行投影 (parallel projection) という.
18 / 40
第 5 章 CG で使われる変換
はじめに
x2=xV2
xV3
x1=xV1
図 5.10: 透視投影
x2=xV2
xV3
∞
x1=xV1
図 5.11: 平行投影
19 / 40
第 5 章 CG で使われる変換
はじめに
視点 xV3 = 0, 投影面 xV3 = d のとき,任意の点 xV から投影点 xD の同次座
標表現 yD への透視投影は

 


yD1
1 0
0
0
xV1
yD2  0 1


0
0

 
 xV2 
yD3  = 0 0


1
0
xV3 
wD
0 0 1/d 0
1
となる.
x2=xV2
xD
xV
xV3
x1=xV1
xV3=d
図 5.12: 原点からの透視投影
20 / 40
第 5 章 CG で使われる変換
はじめに
視点 xV3 = −d, 投影面 xV3 = 0 のとき,任意の点 xV から投影点 x0 の同次
座標表現 y0 への透視投影は
  


y01
1 0
0
0
xV1
y02  0 1


0
0
 =
 xV2 
y03  0 0


0
0
xV3 
w0
0 0 1/d 1
1
となる.d → ∞ のとき,平行投影となる.
x2=xV2
x0
xV
xV3
xV3={d
x1=xV1
図 5.13: xV3 = −d からの透視投影
21 / 40
第 5 章 CG で使われる変換
はじめに
§5.5 OpenGL における変換
OpenGL では同次座標系の変換行列を使って各種変換を行っている.
v0=Pm:::P1An:::A1v
v
A1
:::
An
Point
Geometric
information transformations
P1
:::
Pm
Projective
transformations
Hidden Image
surface
processing
calculation
Picture
図 5.14: 変換行列を使った各種変換
22 / 40
第 5 章 CG で使われる変換
はじめに
変換行列の初期化
glMatrixMode
void glMatrixMode(Glenum mode);
mode に引数 GL MODELVIEW, GL PROJECTION, GL TEXTURE を指定して,
幾何変換,射影変換,テクスチャー行列のどれを操作するか指定する.
glLoadIdentity
void glLoadIdentity(void);
現在対象としている行列を 4x4 の単位行列にする.
23 / 40
第 5 章 CG で使われる変換
はじめに
変換の例
glMatrixMode(GL_PROJECTION); /*射影変換の設定*/
glLoadIdentity(); /*初期化: P_0 = I*/
gluPerspective(60.0, 1.0, 1.0, 10.0); /*P_1*/
...
glMatrixMode(GL_MODELVIEW); /*幾何変換の設定 */
glLoadIdentity(); /*初期化: A_0 = I*/
glTranslatef(-1.0, 0.0, 0.0); /* x 軸方向移動: A_1*/
glRotatef(-30.0, 0.0, 0.0, 1.0); /* 回転: A_2 */
glutWireTeapot(1.0); /* ティーポットを描画: v’=P_1A_2A_1v */
...
24 / 40
第 5 章 CG で使われる変換
はじめに
OpenGL における平行投影変換
glOrtho()
void glOrtho(Gldouble left, Gldouble right,
Gldouble bottom, Gldouble top, Gldouble near,
Gldouble far);
図 5.15 のとおり.
x2=xV2
left
top
near
far
xV3
∞
bottom
x1=xV1
right
図 5.15: OpenGL における平行投影変換
25 / 40
第 5 章 CG で使われる変換
はじめに
OpenGL における透視投影変換
gluPerspective()
void gluPerspective(GLdouble fovy, Gldouble aspect,
GLdouble near, Gldouble far)
図 5.16 のとおり.
x2=xV2
aspect=w=h
w
h
near
far
xV3
fovy
x1=xV1
図 5.16: OpenGL における透視投影変換
26 / 40
第 5 章 CG で使われる変換
はじめに
視点の設定
gluLookAt()
void gluLookAt(GLdouble e1, GLdouble e2, GLdouble e3,
GLdouble c1, GLdouble c2, GLdouble c3, GLdouble u1,
GLdouble u2, GLdouble u3)
図 5.17 のとおり.ただし, u1, u2, u3 は,ウィンドウに表示される画像の上の
方向を示す.
27 / 40
第 5 章 CG で使われる変換
はじめに
x2=xV2
(c1,c2,c3)T with x3-axis
T
(e1,e2,e3) with x3-axis
xV3
x3
(u1,u2,u3)T with x3-axis
x1=xV1
図 5.17: OpenGL における視点の設定
28 / 40
第 5 章 CG で使われる変換
はじめに
平行移動
glTranslatef()
void glTranslatef(GLfloat x1, GLfloat x1, GLfloat x3)
局所座標系を x1 , x2 , x3 軸に x1, x2, x3 だけ移動する.
回転
glRotatef()
void glRotatef(GLfloat angle, GLfloat x1, GLfloat x2,
GLfloat x3)
• angle は度数で指定する.例えば,x1 -x2 平面で 60 度左に回転する場合
glRotatef(60.0, 0.0, 0.0, 1.0) とかく.
拡大・縮小
29 / 40
第 5 章 CG で使われる変換
はじめに
glScalef()
void glScalef(GLfloat x1, GLfloat x2y, GLfloat x3)
各軸方向へ指定された値で伸縮させる.例えば,x1 , x2 方向に半分の大きさにす
る場合 glScalef(0.5, 0.5, 1.0) とかく.
変換行列の保存と呼出し
glPushMatrix
void glPushMatrix()
図 5.18 のとおり.
glPopMatrix
void glPopMatrix()
図 5.18 のとおり.
30 / 40
第 5 章 CG で使われる変換
はじめに
push
stack
I
A2A1
push
pop
A3A2A1
A2A1
glScalef()
glLoadIdentity() glScalef()
glTranslatef() draw ¡quad()
A2A1
pop
A5:::A1
A2A1
A2A1
glTranslatef()
glScalef()
glRotatef()
draw¡tri()
図 5.18: OpenGL における変換行列の保存と呼出し
31 / 40
第 5 章 CG で使われる変換
はじめに
§5.6 ティーポットを描く
ティーポットを平行投影変換で描く.
program5 1.c
int main(int argc, char **argv)
...
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
trackball(quat , 0.0, 0.0, 0.0, 0.0);
...
void display(void)
...
/* ティーポットを描画 */
glColor3f(1.0, 1.0, 1.0);
glutWireTeapot(0.4);
...
32 / 40
第 5 章 CG で使われる変換
はじめに
このプログラムから trackball.h, trackball.c を使う.
マウスのための関数
glutMouseFunc()
void glutMouseFunc(void (*func)(int button, int state,
int x1, int x2))
• func にはマウスのボタンが押されたときに実行する関数のポインタを与
える.
• button には押されたボタン (GLUT LEFT BUTTON,
GLUT MIDDLE BUTTON, GLUT RIGHT BUTTON),state には押した
(GLUT DOWN) のか離した (GLUT UP) のか,x と y にはその位置が渡さ
れる.
33 / 40
第 5 章 CG で使われる変換
はじめに
glutMotionFunc()
void glutMotionFunc(void (*func)(int x1, int x2))
• func には,マウスのいずれかのボタンを押しながらマウスを動かしたとき
に実行する関数のポインタを与える.
• x1 と x2 には、現在のマウスの位置が渡される.
• 設定を解除するには引数に 0(ヌルポインタ)を指定する(stdio.h 等の中
で定義されている記号定数 NULL を使用しても良い).
ダブルバッファリング(ちらつきの原因となる画像の作成過程をみせないため
に,2つのバッファを用いて表示画面を交換すること)のために次の関数が用意
されている.
• glutInitDisplayMode(GLUT DOUBLE) を指定する.
• glFlush() の代りに glutSwapBuffers() を使用する.
34 / 40
第 5 章 CG で使われる変換
はじめに
ティーポットを透視投影変換で描く.
program5 2.c
int main(int argc, char **argv)
...
gluPerspective(70.0, 1.0, 1.0, 10.0);
...
void display(void)
...
/* ティーポットを描画 */
glColor3f(1.0, 1.0, 1.0);
glutWireTeapot(1.0);
...
35 / 40
第 5 章 CG で使われる変換
はじめに
演習 5.6.1 (ティーポットと水滴)
プログラム program5 3.c を修正してティーポットと水滴を図 5.19 のように移動
せよ.
program5 3.c
...
void display(void)
...
// glPushMatrix();
// glTranslatef(0.0, 0.0, 0.0);/* x1 軸方向移動 */
// glRotatef(0.0, 0.0, 0.0, 1.0);/* 回転 */
glColor3f(1.0, 1.0, 1.0);/* 色指定 */
glutWireTeapot(1.0);/* ティーポットを描画 */
// glPopMatrix();
...
36 / 40
第 5 章 CG で使われる変換
はじめに
図 5.19: ティーポットと水滴
37 / 40
第 5 章 CG で使われる変換
まとめ
§5.7 まとめ
CG で使われる幾何変換,投影変換,視野変換の理論と OpenGL を用いた変換
方法についてみてきた.
1
2
3
幾何変換,投影変換,視野変換では同次座標表現が用いられる.
平行移動,回転移動,拡大・縮小,反転移動はそれぞれ同次座標表現の変換
行列で与えられる.一連の変換は,変換行列の積で与えられる.
OpenGL における平行投影変換,透視投影変換,視点の設定,幾何変換の関
数について学んだ.
38 / 40
第 5 章 CG で使われる変換
参考文献
参考文献
[1] 嘉数侑昇, 古川正志.
CAD/CAM/CG のための形状処理工学入門.
森北出版, 1995.
[2] James D. Foley, Steven K. Feiner, Andries van Dam, John F. Hughes, 佐藤義雄 (訳).
コンピュータグラフィックス 理論と実践.
オーム社, 2001.
[3] 千葉則茂, 土井章男.
3次元 CG の基礎と応用.
サイエンス社,, 2004.
[4] OpenGL 公式サイト.
http://www.opengl.org/.
39 / 40
第 5 章 CG で使われる変換
参考文献
参考文献 (cnt.)
[5] 床井浩平.
GLUT による「手抜き」OpenGL 入門.
http://www.wakayama-u.ac.jp/˜tokoi/opengl/libglut.html.
40 / 40