원 그리기 함수 gx_circle()에 추가하여 타원그리기 함수 gx_ellipse()를 추가합니다.

gx_ellipse()

형태 void gx_ellipse( dc_t dc, int center_x, int center_y, int width, int height);
인수 dc_t dc 출력 대상 Device Context
  int center_x
int center_y
타원의 중심 좌표
 

int width
int height

타원의 폭과 높이

gx_ellipse()은 gx_circle()와 gx_rectangle()과 마찬가지로 dc의 pen_color로 테두리를 그리고 brush_color로 내부 색을 채웁니다. 또한 pen_color 나 brush_color 가 clr_clear 일 경우 칠해지지 않습니다.

gx_ellipse()은 타원을 그리는 함수 ellipse()을 호출하면서 내부의 색을 칠해주는 함수의 포인터와 외부의 테두리에 점을 찍은 함수의 포인터를 넘겨 줌으로써 하나의 타원 그리기 루틴으로 두가지 작업을 처리합니다.

void	gx_ellipse( dc_t *dc, int center_x, int center_y, int width, int height)
{
   if ( ( 0 == width) || ( 0 == height) )	return;

   ellipse( dc, center_x, center_y, width, height, dc->brush_color, dc->hline);
   ellipse( dc, center_x, center_y, width, height, dc->pen_color  , circle_dot);
}

gx_ellipse()에서 색상에 따라 두번의 호출을 하면서 선을 그리는 hline()과 circle_dot() 함수를 넘겨 줍니다.

static void ellipse( dc_t *dc, int x_center, int y_center, int x_width, int y_height, int color, void (*fun)( dc_t *dc, int, int, int, int))
{
   int		x_coor, y_coor;
   long     width, height;
   long     xone_squ, xtwo_squ;
   long     yone_squ, ytwo_squ;
   long     delta, dx, dy;
   
   if (clr_clear == color)		return;
   
   x_coor   = 0;
   y_coor   = y_height;
   width    = x_width;
   height   = y_height;
   xone_squ = width * width;
   xtwo_squ = xone_squ << 1;
   yone_squ = height * height;
   ytwo_squ = yone_squ << 1;

   delta    = yone_squ - xone_squ *height + (xone_squ >> 2);
   dx       = 0;
   dy       = xtwo_squ * height;

   while( dx < dy )
   {
		fun( dc, x_center-x_coor, x_center+x_coor, y_center+y_coor, color);
      fun( dc, x_center-x_coor, x_center+x_coor, y_center-y_coor, color);

      if( delta > 0 )
      {
         y_coor--;
         dy    -= xtwo_squ;
         delta -= dy;
      }
      x_coor++;
      dx       += ytwo_squ;
      delta    += yone_squ + dx;
   }

   delta += ( 3*(xone_squ - yone_squ)/2 - (dx+dy)/2 );

   while( y_coor >= 0 )
   {
		fun( dc, x_center-x_coor, x_center+x_coor, y_center+y_coor, color);
      fun( dc, x_center-x_coor, x_center+x_coor, y_center-y_coor, color);

		if( delta < 0 )
      {
         x_coor++;
         dx      += ytwo_squ;
         delta   += dx;
      }
      y_coor--;
      dy      -= xtwo_squ;
      delta   += xone_squ - dy;
   }
}

이 함수에서 실제로 원을 그리는 함수는 fun() 입니다. 이 함수에 따라서 점의 테두리를 위한 점을 찍을 수 있으며, 또는 원의 내부를 칠할 수 있습니다.

원의 테두리 점을 찍는 함수는 인수로 받은 좌표를 좌우로 해서 점을 출력하게 됩니다.

static void circle_dot( dc_t *dc, int fst_x , int snd_x , int coor_y, int color)
{
   dc->set_pixel( dc, fst_x, coor_y, color);
   dc->set_pixel( dc, snd_x, coor_y, color);
}

sample 소스 설명

int   rand_color( dc_t *dc)     // 색상을 랜덤하게 구한다.
{
   return ( gx_color( dc, rand() %128 +128, rand() %128 +128, rand() %128 +128));
}

void  test_ellipse( dc_t *dc)
{
   int         coor_x, coor_y;
   int         width,  height;
   static int  ndx         = 0;
                                  
   coor_x         = rand() % dc->width;     // 타원의 중심 좌표와 크기를 랜덤하게 구한다.
   coor_y         = rand() % dc->height;
   width          = rand() % 200;
   height         = rand() % 200;

   if ( !( ndx % 60))   gx_clear( dc, clr_black);

   switch ( (ndx++ / 20) % 3)  
   {
   case 0   :
            dc->pen_color     = rand_color( dc);
            dc->brush_color   = clr_clear;
            break;
   case 1   :
            dc->pen_color     = clr_clear;
            dc->brush_color   = rand_color( dc);
            break;
   default  :
            dc->pen_color     = rand_color( dc);
            dc->brush_color   = rand_color( dc);
            break;
   }
   gx_ellipse( dc, coor_x, coor_y, width, height);                  // 랜덤한 좌표와 크기로 타원을 출력
   usleep( 150 *1000);
}

void  test( void)
{
   화면에 대한 Device Context를 구하고 성공하면 test_circle() 호출
}

int   main( void)
{
   gx 라이브러리를 초기화하고 성공하면 test() 호출
}

프로그램을 실행하면 아래와 같이 계속 원을 출력하게 됩니다.

 태그: *그래픽 *라이브러리 *그래픽라이브러리