그래픽 & 멀티미디어
글 수 111
2007.04.23 18:14:07 (*.239.53.178)
40515
이번 시간에는 원 그리기에 대해서 알아 보겠습니다. 역시 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
태그: *그래픽