Skip to main content
1 
Graphics with Processing 
2013-09 投影変換と隠面消去 
http://vilab.org 
塩澤秀和
2006-2013 H. SHIOZAWA http://vilab.org 
2 
9.1 投影変換(p.32) 
ビューイングパイプライン平行投影 
透視投影 
投影面 
投影面 
視点 
3次元頂点情報 
(ローカル座標系) 
モデルビュー変換 
(→視点座標系) 
投影変換 
(→正規化視体積) 
ビューポート変換 
(→画面座標系) 
2次元描画 
モデリング変換 
(→ワールド座標系) 
ビューイング変換 
(→視点座標系)
2006-2013 H. SHIOZAWA http://vilab.org 
3 
9.2 透視投影(p.35) 
透視投影 
 視体積(ビューボリューム) 
 画角(視野角) ⇒ 見える範囲 
 画角大=広角,画角小=望遠 
 透視投影の視体積は四角錘台 
 正規化視体積 
 各座標の値を-1~+1に正規化 
 四角錐台→ 立方体 
 空間が歪み,視点から遠いもの 
ほど大きく縮む⇒ 遠近感 
 z座標は0~1にする方式もある 
x 
(-1,-1,+1) 
(+1,+1,-1) 
(+1,+1,+1) 
(-1,-1,-1) 
座標系の取り方やz座標の計算 
方法はOpenGL, DirectXなど 
システムによって若干異なる 
(-kx,-ky,-n) 
x 
z y 
視線 
視点 
(原点) 
(kx,ky,-n) 
z=-f 
画角(視野角)
2006-2013 H. SHIOZAWA http://vilab.org 
4 
9.3 透視投影の計算(p.36参考) 
視体積の正規化 
x n x z n :  :  (y軸も同様) 
n 
n 
x x n n  
   , 
x,y座標を-1~+1の範囲に収める 
n 
   
p  
y 
x 
n 
n 
  
p  
x 
z ( f  n )  
2 
fn 
z p   
z f n 
( ) 
  
z 
k 
y 
y 
(x, z) 
x(またはy) 
(xn, -n) 
O -n -f 
z座標も,-1~+1の範囲に収める 
z=-n のときzp=+1.0 
z=-f のときzp= -1.0 
三角形の相似より(z<0に注意) 
z 
y y 
z 
  
 
z 
k 
k 
x 
x x 
OpenGL/Processingの計算式⇒ 
(教科書の方式は,0.0~1.0) 
kx 
z 
-kx 
z
2006-2013 H. SHIOZAWA http://vilab.org 
 
 
 
 
5 
9.4 透視投影行列(p.36参考) 
 同次座標で表現 透視投影行列 
 OpenGL/Processingの方式 
 
 
 
 
 
 
 
 
0 0 0 
n 
n 
0 0 0 
f  
n 
 
 
 
 
 
 
 
 
 
p 
 
x 
y 
p 
 
2 
0 0 
z 
p 
proj proj view P  M P 
 ここまでの座標変換の合成 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fn 
 
 
 
 
 
 
 
 
 
 
 
 
x 
y 
1 
0 0 1 0 
z 
f n 
f n 
k 
k 
w 
y 
x 
p 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
p 
 
p 
x 
y 
 
p 
 
 
 
 
 
 
 
 
 
 
 
 
p 
p 
p 
p 
z 
w 
x 
y 
z 
   
x x w 
p p p 
   
y y w 
p p p 
  
z z w 
p p p 
    
f n 
n 
p 
w z 
n 
fn 
f n 
z 
 
f n 
z 
y 
k 
x y 
k 
x 
p 
y 
p 
x 
p 
   
 
 
 
   
2 
proj proj view local P M M M P model  
9.3の式を同次座標で表す 
このときw'p = -z とすると便利 
w'pに視点からの 
奥行情報が残る
2006-2013 H. SHIOZAWA http://vilab.org 
6 
60° 
画面の表面 
視点 
d  H 3 2 
n  d 10 
H  height 
f  d 10 
9.5 透視投影関数 
 perspective(fov, aspect, n, f) 
 ただし,すべての引数はゼロ以外 
 aspectは,floatで計算すること 
 バージョン1.x ⇒ OPENGLが正確 
W 
H 
透視投影関数 
n 
f 
aspect=W/H 
fov 
画角 
(視野角) 
視体積の縦横比 
前方・後方クリッピ 
視点ング面までの距離 
 Processingのデフォルト設定 
 perspective()を呼ばない場合 
 または,引数なしで呼んだ場合 
 画角(視野角) = 60°(π / 3) 
 aspect = width / height
2006-2013 H. SHIOZAWA http://vilab.org 
7 
9.6 ビューポート変換とクリッピング 
ビューポート変換(p.42) 
 正規化視体積 
 デバイス座標系 
3次元クリッピング(p.44) 
 線分のクリッピング 
 コーエン・サザランド法(4.6) 
 z座標を加えた6ビットコード 
 ポリゴンのクリッピング 
 ポリゴンの形状が変わるので, 
分割処理等が必要になる 
 特に三角形しか扱えない場合 
x 
(-1,-1,+1) 
(+1,+1,-1) 
(0,0) 
画面サイズに 
引き伸ばす 
(width, height) 
ポリゴン 
正規化 
視体積
2006-2013 H. SHIOZAWA http://vilab.org 
8 
9.7 隠面消去(1) 
隠面消去(隠線・隠面処理) 
 隠面消去とは 
 他の物体などに隠れて見えない 
物体(の全部または一部)を描 
画しない処理 
 弱点を補い合ういくつかの手法 
を組み合わせることもある 
 奥行きソート法(p.102) 
 ポリゴンをz座標(視点座標)で 
並び替え,遠くから順に描画 
 細長いポリゴンで問題が生じる 
 バックフェースカリング(p.100) 
 ポリゴンに表裏を設定し,裏側を 
向いているポリゴンを描画しない 
 表裏はポリゴン作成時の頂点の 
順序(右回り・左回り)で指定 
 各凸多面体での隠面消去 
裏 
表 
裏 
表 
裏 
表向き 
1 
2 3 
4 
5 
裏向き 
2 
1 
3 
4 
5 
z 
1 
2 
3 
4
2006-2013 H. SHIOZAWA http://vilab.org 
9 
9.8 隠面消去(2) 
 Zバッファ法(p.107) 
 画面上の全ピクセルにz座標を 
持たせ,1点1点描画するときに 
遠近関係をチェックする 
 単純&高速⇒ ハードウェア化 
 半透明の重なりの処理に難点 
 スキャンライン法(p.105) 
 ピクセル横1行(スキャンライン) 
ごとにポリゴンの断面の重なりを 
数学的に計算し,描画する 
 計算は複雑だが,使用メモリが 
少ない 
-∞ 
-50 
-60 
-60 
Zバッファ 
視線 
視体積の断面 
-60 -∞ 
-50 
-50 
-∞ 
視点 
ピクセル 
視体積 
視点
2006-2013 H. SHIOZAWA http://vilab.org 
10 
9.9 演習課題 
課題 
問1) 9.10のプログラムに適切な処 
理を補って,実行してみなさい 
 バージョン1.xならOPENGLで 
1. 紙飛行機が遠くから手前に近づ 
いてきて,カメラの横を飛び去っ 
ていくようにしなさい 
 飛び去ったら,元の位置に戻っ 
て繰り返すようにしなさい 
 ヒント: translate 
2. カメラの向きを紙飛行機をずっと 
追跡するようにしなさい 
 ヒント: camera 
3. マウスのボタンでカメラを望遠に 
切り替えられるようにしなさい 
 ヒント: perspective 
問2) 下図は投影変換の原理を示し 
たものである(ウィンドウサイズは 
200×200,画角は60°とする) 
1. P’のz座標s を求めなさい 
2. 視点座標系で(0, 100, -300) 
に変換された点Pが,投影面上に 
写像される座標P'を求めなさい 
 次回,A4レポート用紙で提出 
y 
100 
O 
z 
P' 
60° s 
P(0, 100, -300) 
-300 
投影面=ウィンドウ 
-100
2006-2013 H. SHIOZAWA http://vilab.org 
11 
9.10 演習課題(続き) 
void draw() { 
background(50, 50, 100); 
// 画角の設定 
perspective(PI/3, (float) width / 
height, 10, 10000); 
// カメラの位置と撮影目標の設定 
camera(-150, -500, 1500, 
0, 0, 0, 0, 1, 0) ; 
// 照明の光を上からに変更 
pushMatrix(); 
rotateX(PI/2); lights(); 
popMatrix(); 
fill(255); noStroke(); 
pushMatrix(); 
translate(0, -300, 1200); 
paperplane(); 
popMatrix(); 
fill(0, 50, 0); noStroke(); 
for (int i = -10; i <= 10; i++) { 
for (int j = -10; j <= 10; j++) { 
pushMatrix(); 
translate(i*200, 0, j*200); 
box(180, 10, 180); 
popMatrix(); 
} 
} 
} 
// 紙飛行機のモデル 
void paperplane() { 
beginShape(TRIANGLE_FAN); 
vertex(0, 0, 0); 
vertex(-30, 5, -50); 
vertex(-5, 0, -50); 
vertex(0, 20, -50); 
vertex(5, 0, -50); 
vertex(30, 5, -50); 
endShape(); 
}
2006-2013 H. SHIOZAWA http://vilab.org 
12 
9.11 参考:平行投影(p.37) 
平行投影(直交投影) 
 視体積(ビューボリューム) 
 視体積=「見える領域」 
 平行投影の視体積は直方体 
平行投影関数 
 ortho(xmin, xmax, ymin, ymax, 
zmin, zmax) 
 正規化視体積 
 各座標の値を-1~+1に正規化 
 直方体→ 立方体 
 z座標は0~1にする方式もある 
 計算式 
xmin xmax 
ymin 
ymax 
zmin 
zmax 
(-1,-1,-1) 
x 
(-1,-1,+1) 
(+1,+1,-1) 
(+1,+1,+1) 
x x x 
2  (  
) 
max min xp  
x x 
max min 
 
y, z も同様(教科書はzは0~1)
2006-2013 H. SHIOZAWA http://vilab.org 
13 
9.12 参考:平行投影行列(p.37参考) 
 平行投影の計算 
xmax-xmin 
x 
2 
xp 
 変換行列による表現 
min 
x  
x 
x x 
max min 
x x x 
2  (  
) 
max min 
x  
x 
max min 
max min 
x x 
max min 
2 
x 
max min 
2 1 
x x 
x x 
xp 
 
 
 
 
 
 
  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x  
x 
max min 
y  
y 
max min 
z  
z 
max min 
 
 
0 0 
0 
2 
 
 
 
2 
 
 
 
2 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x 
y 
1 
0 
0 0 
0 0 0 1 
x 
y 
p 
p 
1 
max min 
max min 
max min 
max min 
max min 
max min 
z 
z z 
z z 
y y 
y y 
x x 
x x 
z 
p 
視点 
座標 
正規化 
視体積 
の座標 
y座標, 
z座標も 
同様 
xmin xmax 
-1 +1 
視点座標 
正規化 
視体積