이번 시간에는 원 그리기에 대해서 알아 보겠습니다. 역시 Bresenham 알고리듬에 따라 코드를 작성하겠습니다. 선 긋기와는 달리 이번 원 그리기에 대해서는 Bresenham 알고리듬에 대한 설명은 생략하겠습니다. 그러나 선 그리기와 마찬가지로 원에 가까운 좌료를 찾아 점을 찍는 기본 원리는 같습니다.

원은 좌우, 상하가 대칭이므로 모든 점의 좌표를 구하지 않고 옆의 그림에서 처럼 하나의 좌표로 나머지 대칭 자표를 찾도록 합니다.

 

 

 

바로 브레슨햄의 원 그리기 예제입니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>        // abs

#include <unistd.h>        // open/close
#include <fcntl.h>         // O_RDWR
#include <sys/ioctl.h>     // ioctl
#include <sys/mman.h>      // mmap PROT_
#include <linux/fb.h>

int   screen_width;
int   screen_height;
unsigned short *fb_mapped;


void  dot( int x, int y)
{
   unsigned short *ptr;

   if ( 0 <= x && 0 <= y && x < screen_width && y < screen_height)
   {
      ptr   = fb_mapped + screen_width * y + x;
     *ptr  = 0xffff;
   }
}

static void ploat_circle( int x_center, int y_center, int x_coor, int y_coor)
{
   dot( x_center +x_coor, y_center +y_coor);
   dot( x_center -x_coor, y_center +y_coor);
   dot( x_center +x_coor, y_center -y_coor);
   dot( x_center -x_coor, y_center -y_coor);
   dot( x_center +y_coor, y_center +x_coor);
   dot( x_center -y_coor, y_center +x_coor);
   dot( x_center +y_coor, y_center -x_coor);
   dot( x_center -y_coor, y_center -x_coor);
}

void  circle( int x_center, int y_center, int radius)
{
   int      x_coor;
   int      y_coor;
   int      p_value;

   x_coor   = 0;
   y_coor   = radius;
   p_value   = 3 - 2 * radius;
   while   ( x_coor < y_coor)
   {
      ploat_circle( x_center, y_center, x_coor, y_coor);
      if ( p_value < 0)
      {
         p_value   += 4 * x_coor +6;
      }
      else
      {
         p_value   += 4 * ( x_coor -y_coor) +10;
         y_coor--;
      }
      x_coor++;
   }
   if ( x_coor == y_coor)
      ploat_circle( x_center, y_center, x_coor, y_coor);
}


int   main( int argc, char **argv)
{
   int      fb_fd;
   struct   fb_var_screeninfo  fbvar;
   struct   fb_fix_screeninfo  fbfix;
   int      bytes_per_line;
   int      mem_size;

   if ( access( "/dev/fb", F_OK))
   {
      printf( "프레임 버퍼 장치가 없습니다.n");
      return 0;
   }

   if ( 0 > ( fb_fd = open( "/dev/fb", O_RDWR)))
   {
      printf( "프레임 버퍼에 접근할 수 없습니다.n");
      return 0;

   }

   if ( ioctl( fb_fd, FBIOGET_VSCREENINFO, &fbvar))
   {
      printf( "FBIOGET_VSCREENINFO를 실행하지 못했습니다.n");
      return 0;
   }
   if ( ioctl( fb_fd, FBIOGET_FSCREENINFO, &fbfix))
   {
      printf( "FBIOGET_FSCREENINFO 실행하지 못했습니다.n");
      return 0;
   }

   screen_width   = fbvar.xres;                    // 스크린의 픽셀 폭
   screen_height  = fbvar.yres;                    // 스크린의 픽셀 높이
   bytes_per_line = fbfix.line_length;             // 한개 라인 당 바이트 개수

   mem_size       = bytes_per_line * screen_height;

   fb_mapped      = ( unsigned short *)mmap( 0,
                                          mem_size,
                                          PROT_READ|PROT_WRITE,
                                          MAP_SHARED,
                                          fb_fd,
                                          0);


   if ( 4 != argc)
   {
      printf( "사용방법: $]./sample x y rn");
   }
   else
   {
      circle( atoi( argv[1]), atoi( argv[2]), atoi( argv[3]) );
   }

   munmap( fb_mapped, mem_size);
   close( fb_fd);

   return 0;
}

실행해 보면 아래와 같습니다.

]$ ./sample 400, 400, 100
]$ ./sample 400, 400, 70
]$ ./sample 400, 400, 50
]$ ./sample 400, 400, 30
]$ ./sample 0, 0, 750
]$ ./sample 300, 300, 300
]$ ./sample 100, 100, 100
]$ ./sample 200, 200, 100

태그: *그래픽