コンピューターでアニメーションを作成する場合,シーン毎の座標をデータとして指定す ると大変面倒である.シーン毎に膨大なデータが必要となるからである.データを軽減す るために,動きは計算により求めることが多い.
アニメーションは,次のようにして描いている.
1 #include <stdio.h> 2 #include <GL/glut.h> 3 #include <math.h> 4 5 //---- プロトタイプ宣言 ----- 6 void draw(void); // 図を描く 7 void resize(int w, int h); // サイズの調整 8 void anime(void); // アニメーション 9 void set_color(void); // 塗りつぶし色の設定 10 11 //---- グローバル変数 ------- 12 double theta = 0.0; // プロペラの角度,初期値 13 double deg = M_PI/180; // 度をラジアンに 14 15 //==================================================================== 16 // main関数 17 //==================================================================== 18 int main(int argc, char *argv[]) 19 { 20 glutInitWindowPosition(100,200); // 初期位置(x,y)指定 21 glutInitWindowSize(200,200); // 初期サイズ(幅,高さ)指定 22 glutInit(&argc, argv); // GLUT 初期化 23 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); // 表示モードの指定 24 glutCreateWindow("windmill"); // windowをタイトルを付けてを開く 25 glutDisplayFunc(draw); // イベントにより呼び出し 26 glutReshapeFunc(resize); // サイズ変更のときに呼び出す関数指定 27 glutIdleFunc(anime); // 暇なときに実行(アニメーション) 28 set_color(); // 塗りつぶす色指定 29 glutMainLoop(); // GLUTの無限ループ 30 31 return 0; 32 } 33 34 //==================================================================== 35 // 図形を描く 36 //==================================================================== 37 void draw(void) 38 { 39 double l1=0.7, l2=0.05; 40 double dthe; 41 int i; 42 43 glClear(GL_COLOR_BUFFER_BIT); 44 // ---- タワー --------- 45 glColor3d(0.5, 1.0, 0.5); // 線の色指定(RGB) 46 glBegin(GL_POLYGON); 47 glVertex2d(-0.1, -0.9); 48 glVertex2d(-0.05, 0.1); 49 glVertex2d( 0.05, 0.1); 50 glVertex2d( 0.1, -0.9); 51 glEnd(); 52 53 // ---- プロペラ --------- 54 glColor3d(1.0, 1.0, 1.0); // 線の色指定(RGB) 55 for(i=0; i<3; i++){ 56 glBegin(GL_POLYGON); 57 dthe=i*120; // プロペラの3軸の角度 58 glVertex2d(0.0, 0.0); 59 glVertex2d(l2*cos((theta+dthe-60)*deg), l2*sin((theta+dthe-60)*deg)); 60 glVertex2d(l1*cos((theta+dthe)*deg), l1*sin((theta+dthe)*deg)); 61 glVertex2d(l2*cos((theta+dthe+60)*deg), l2*sin((theta+dthe+60)*deg)); 62 glEnd(); 63 } 64 65 glutSwapBuffers(); // 描画 66 } 67 68 69 //==================================================================== 70 // リサイズ 71 // この関数は window のサイズが変化したら呼び出される 72 // 引数 73 // w:ウィンドウの幅 74 // h:ウィンドウの高さ 75 //==================================================================== 76 void resize(int w, int h) 77 { 78 glLoadIdentity(); // 変換行列を単位行列に 79 gluOrtho2D(-w/200.0, w/200.0, -h/200.0, h/200.0); // world座標系の範囲 80 glViewport(0, 0, w, h); // ウィンドウ座標系を指定 81 } 82 83 //==================================================================== 84 // PCが暇なときに実行する.これが実行されるとアニメーションが描かれる 85 //==================================================================== 86 void anime(void) 87 { 88 theta += 0.02; 89 if(theta>=360) theta-=360; // 360度を超えた処理 90 glutPostRedisplay(); 91 } 92 93 //==================================================================== 94 // 色の指定 95 //==================================================================== 96 void set_color(void) 97 { 98 glClearColor(0.0, 0.0, 1.0, 1.0); //赤緑青と透明度 99 }
プロペラは,GL_POLYGONを使って描く.しかし,これは凸の図形しか描くことがで きないので,プロペラの羽を一つずつ描いてそれを足しあわせて一つのプロペラとする.
ひとつの羽は,図3のような座標系を用いる.角度を用い て,図中の4つの座標を表現する必要がある.三角関数の知識を使うと,次のようになる.
(1) | |||||
(2) | |||||
(3) | |||||
(4) |