OpenGLを用いてC言語で矢印を描くプログラム
openglでC言語を用いて矢印を描く必要があった。
以下の理由で、自分で関数を作成した。
動作結果
最初に動作結果を載せる。挙動のさせ方は関数への引数で決まる。今回は円上の点を追うようにした。openglの座標系は以下のようになっている
今回は以下のような設計にした。x,y平面上で動作する2Dモデルとする。
GL_POLYGONやGL_QUADSを使う場合、図のような内側にへこんだ図形は正しく描くことができない。
このような図形を描くときは、三角形に分割して、GL_TRIANGLE_STRIPなどを使って描く必要がある。
参照
ただ頂点だけを結んでPOLYGON表示させた場合
LINE_LOOPであれば描く事は可能
よって矢印を描く場合は、以下のように三角形と四角形に分けて描写した以下、ソース。includeするヘッダーファイルが正しく表示されない為、以下のヘッダをincludeして利用してください
/* arrow.c Copyright (c) 2012 by Chikara Morito All rights reserved */
/*
x1,y1 始点の座標
x2,y2 動かしたい座標
length_arrow 矢全体の長さ
width_arrow 尾の幅
scele 比率...これを帰ると矢印の大きさが変わる
*/
#define KEY_ESC 27
void timer(int value){
glutPostRedisplay();
glutTimerFunc(10,timer,0);
}
void glDrawArrowd(float x1, float y1,float x2, float y2,float length_arrow,float width_arrow,float scale);
void display( void )
{
static float x,y;
static int deg;
glClear( GL_COLOR_BUFFER_BIT );
x = 10*cos(deg*M_PI/180);
y = 10*sin(deg*M_PI/180);
glDrawArrowd(0,0,x,y,8,2,1);
deg++;
if(deg == 360){
deg =0;
}
}
void myKbd( unsigned char key, int x, int y )
{
if ( key == KEY_ESC ) exit( 0 );
}
void myInit ( char *progname )
{
int width = 500, height = 500;
glutInitWindowPosition( 0, 0 );
glutInitWindowSize( width, height );
glutInitDisplayMode( GLUT_RGBA );
glutCreateWindow( progname );
glClearColor ( 0.0, 0.0, 0.0, 1.0 );
glutKeyboardFunc( myKbd );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -20.0, 20.0, -20.0, 20.0, -20.0, 20.0 );
}
void glDrawArrowd(float x1, float y1,float x2, float y2,float length_arrow,float width_arrow,float scale)
{
double deg;
float length,width;
double sn,cs;
float ratio;
length = scale*length_arrow;
width = scale*width_arrow;
deg = atan2(y2-y1,x2-x1);
sn = sin(deg);
cs = cos(deg);
//矢印の傘の部分と棒の部分の長さの比率は1:2とする。
//普通に計算するとintの型変換で0になるのでratio変数へ格納
ratio = (float)2/(float)3;
glColor3f( 0, 1.0, 0 );
glBegin(GL_QUADS);
glVertex3f(x1+width/2*sn,y1-width/2*cs,0);
glVertex3f(x1+width/2*sn+ratio*length*cs,y1-width/2*cs+ratio*length*sn,0);
glVertex3f(x1-width/2*sn+ratio*length*cs,y1+width/2*cs+ratio*length*sn,0);
glVertex3f(x1-width/2*sn,y1+width/2*cs,0);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(x1+ratio*length*cs,y1+ratio*length*sn,0);
glVertex3f(x1+width/2*sn+ratio*length*cs+width*sn,y1-width/2*cs+ratio*length*sn-width*cs,0);
glVertex3f(x1+length*cs,y1+length*sn,0);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(x1+length*cs,y1+length*sn,0);
glVertex3f(x1-width/2*sn+ratio*length*cs-width*sn,y1+width/2*cs+ratio*length*sn+width*cs,0);
glVertex3f(x1+ratio*length*cs,y1+ratio*length*sn,0);
glEnd();
glFlush();
}
int main( int argc, char** argv )
{
glutInit( &argc, argv );
myInit( argv[0] );
glutDisplayFunc( display );
glutTimerFunc(1,timer,0);
glutMainLoop();
return( 0 );
}