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
© Copyright 2024 ExpyDoc