OpenGL 03 行列スタック 第2回のおさらい:幾何変換 変換行列を作る関数たち 平行移動 glTranslatef(tx, ty, tz); tx,ty,tzは各軸方向への移動量 回転 glRotatef(θ, x, y, z); θは回転角度(°),x,y,zは回転軸のベクトル 拡大・縮小 glScalef(sx, sy, sz); sx,sy,szは各軸方向の拡大率で,マイナスの値で座標系が 反転する 【解説】課題2-1(幾何変換) http://otsuki.emp.tsukuba.ac.jp/lecture/shibaura/ 2014/GL_step2.zip 幾何変換を用いて,Afterのように描画しなさい 移動量や回転角度は大まかで構いません Before After 【解説】課題2-1(幾何変換) カメラはどこからどこ をどう見ている? →resize関数内 y gluLookAt(0.0,0.0,0.1, 0.0,0.0,0.0, 0.0,1.0,0.0); z軸方向に0.1 移動した所から 原点を y軸上向きで見る x OpenGLは右手系なので z軸は奥から手前向き After 【解説】課題2-1(幾何変換) ありがちなパターン ※オブジェクト描画部分(practice1_disp) // ‐‐ 赤色のオブジェクト描画 ‐‐ glColor3f( 1.0, 0.0, 0.0 ); // 描画オブジェクトの色設定(r,g,b) glutWireCube( 1.0 ); // ワイヤーフレームの立方体を描画(1辺の長 さ) y x // ‐‐ 緑色のオブジェクト描画 ‐‐ glTranslatef( 0.6, ‐0.6, 0.0 ); // 平行移動 glColor3f( 0.0, 1.0, 0.0 ); glutWireCube( 1.0 ); // ‐‐ 青色のオブジェクト描画 ‐‐ glTranslatef( ‐0.6, ‐0.4, 0.0 ); glColor3f( 0.0, 0.0, 1.0 ); glutWireCube( 1.0 ); glFlush(); // 実行されていないOpenGLの命令 を実行 そのあとの諸々… OpenGLは右手系なので z軸は奥から手前向き After 変換行列A1は 2回の平行移動を あわせたもの 【解説】課題2-1(幾何変換) 回避方法 // ‐‐ 赤色のオブジェクト描画 ‐‐ glColor3f( 1.0, 0.0, 0.0 ); // 描画オブジェクトの色設定(r,g,b) glutWireCube( 1.0 ); // ワイヤーフレームの立方体を描画(1辺の 長さ) y x // ‐‐ 緑色のオブジェクト描画 ‐‐ glTranslatef( 0.6, ‐0.6, 0.0 ); // 平 行移動 glColor3f( 0.0, 1.0, 0.0 ); glutWireCube( 1.0 ); glTranslatef( ‐0.6, 0.6, 0.0 ); // ‐‐ 青色のオブジェクト描画 ‐‐ glTranslatef( ‐0.6, ‐0.4, 0.0 ); glColor3f( 0.0, 0.0, 1.0 ); glutWireCube( 1.0 ); glTranslatef( 0.6, 0.4, 0.0 ); OpenGLは右手系なので z軸は奥から手前向き ここで 逆変換を するのが ポイント After 変換行列A1を 逆行列A1-1で 打ち消し 今日はもうちょっと スマートなやり方を 紹介します 行列スタックで解決! 行列スタックとは glPushMatrix() glPopMatrix() 呼ばれた時の行列を保存する 保存した行列の状態に戻す glutSolidSphere( 1.0, 10, 10); glPushMatrix(); glTranslatef( 3.0, 0.0, 0.0); glutSolidCube(1.5); glPopMatrix(); glutWireSphere( 1.5, 10, 10); glTranslatef() が なかったことになる 行列スタックの利点 スタックを使用しない場合 glTranslatef( 0.0, ‐0.5, 0.0) glutSolidCube(2.0); //顔 glTranslatef( ‐0.5, 0.0, 1.0); glutSolidSphere( 0.3, 10, 10); //右目 glTranslatef( 1.0, 0.0, 0.0); glutSolidSphere( 0.3, 10, 10); //左目 glTranslatef( ‐0.5, ‐0.6, 0.2); glutSolidBox( 1.0, 0.3, 0.5); //口 目を上にあげたい 行列スタックの利点 スタックを使用しない場合 glTranslatef( 0.0, ‐0.5, 0.0) glutSolidCube(2.0); //顔 glTranslatef( ‐0.5, 0.4, 1.0); glutSolidSphere( 0.3, 10, 10); //右目 口も上がってしまった… glTranslatef( 1.0, 0.0, 0.0); glutSolidSphere( 0.3, 10, 10); //左目 glTranslatef( ‐0.5, ‐0.6, 0.2); glutSolidBox( 1.0, 0.3, 0.5); //口 変更した箇所以降のすべてに影響 行列スタックの利点 スタックを使用した場合 glTranslatef( 0.0, ‐0.5, 1.0) glPushMatrix(); glutSolidCube(2.0); //顔 glPopMatrix(); glPushMatrix(); glTranslatef( ‐0.5, 0.0, 1.0); glutSolidSphere( 0.3, 10, 10); //右目 glPopMatrix(); glPushMatrix(); glTranslatef( 0.5, 0.0, 1.0); glutSolidSphere( 0.3, 10, 10); //左目 glPopMatrix(); glPushMatrix(); glTranslatef( 0.0, ‐0.6, 1.2); glutSolidBox( 1.0, 0.3, 0.5); //口 glPopMatrix(); 行列スタックの利点 スタックを使用した場合 glTranslatef( 0.0, ‐0.5, 1.0) glPushMatrix(); glutSolidCube(2.0); //顔 glPopMatrix(); glPushMatrix(); glTranslatef( ‐0.5, 0.4, 1.0); glutSolidSphere( 0.3, 10, 10); //右目 glPopMatrix(); glPushMatrix(); glTranslatef( 0.5, 0.4, 1.0); glutSolidSphere( 0.3, 10, 10); //左目 glPopMatrix(); glPushMatrix(); glTranslatef( 0.0, ‐0.6, 1.2); glutSolidBox( 1.0, 0.3, 0.5); //口 glPopMatrix(); 目(指定した箇所)のみ 移動できた ネスティング(入れ子構造) glPushMatrix,glPopMatrixを階層的に用いる void drawRobotFace(){ glPushMatrix(); glutSolidCube(2.0); //顔 glPopMatrix(); glPushMatrix(); //目 glTranslatef( 0.0, 0.4, 1.0); glPushMatrix(); glTranslatef( ‐0.5, 0.0, 0.0); glutSolidSphere( 0.3, 10, 10); //右目 glPopMatrix(); glPushMatrix(); glTranslatef( 0.5, 0.0, 0.0); glutSolidSphere( 0.3, 10, 10); //左目 glPopMatrix(); glPopMatrix(); glPushMatrix(); glTranslatef( 0.0, ‐0.6, 1.2); glutSolidBox( 1.0, 0.3, 0.5); glPopMatrix(); } //口 課題3-1 http://otsuki.emp.tsukuba.ac.jp/lecture/shibaura/ 2014/GL_step3.zip ロボの頭をその場で30度回転させなさい Before After 課題3-2 ロボの頭を2つ横に並べなさい Before After 課題3-3 課題3-2で並べたロボの頭を,図を参考にして 立てなさい Before After 課題3-4 課題3-3で立てたロボの塔の上のロボだけを 反転させなさい Before After 課題3-5 ロボットの塔をその場で45度回転させなさい Before Before After After 課題5が終わった人は自分でいろんな立体を作ってみよう 課題解答 翌日以降に以下のURLにアップしておきます 課題3 http://otsuki.emp.tsukuba.ac.jp/lecture/shibaura/2014/ GL_step3_ans.zip
© Copyright 2024