그래픽 & 멀티미디어
글 수 111
2007.04.25 22:28:33 (*.239.53.178)
37724
원을 알아보았으니까 이번에는 타원을 알아봐야 갰지요. 역시 정수 계산만으로 타원을 그리는 방법입니다만 이렇게 실수를 사용하지 않고 타원을 그린다는 자체가 참 신기하기만 합니다.
한가지 아래의 코드는 제가 아주 오래전에 어디서 구한 코드입니다. 그런데 아쉽게도 코드를 구해놓고 정작 출처를 잊어버렸네요. 제 기억으로는 아래의 코드는 브레슨햄의 알고리듬을 이용한 것은 아닙니다. 그러나 나눗셈이 있더라도 루프 밖에 있고, 작업이 많은 루프 안에서는 역시 정수 덧셈과 뺄셈만 있습니다.
구현한 함수는 ellipse() 로,
void ellipse( int x_center, int y_center, int x_width, int y_height)
x_center, y_center 는 타원의 중심을 가리킵니다. x_width 와 y_height 는 타원의 폭과 높이를 지정하면 됩니다.
*** 혹 이글을 보시고 출처를 알고 계시거나 브레슨햄의 타원 코드를 가지고 계신 분이 계신다면 http://forum.falinux.com의 게시판에 알려 주신다면 매우 감사하겠습니다.
#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; } } void ellipse( int x_center, int y_center, int x_width, int y_height) { int x_coor, y_coor; long width, height; long xone_squ, xtwo_squ; long yone_squ, ytwo_squ; long delta, dx, dy; 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 ) { 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); 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 ) { 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); if( delta < 0 ) { x_coor++; dx += ytwo_squ; delta += dx; } y_coor--; dy -= xtwo_squ; delta += xone_squ - dy; } } 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; int ndx; fb_fd = open( "/dev/fb", O_RDWR); ioctl( fb_fd, FBIOGET_VSCREENINFO, &fbvar); ioctl( fb_fd, FBIOGET_FSCREENINFO, &fbfix); 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); for ( ndx = 20; ndx < 200; ndx+=20) { ellipse( 250, 250, ndx, 200); ellipse( 250, 250, 200, ndx); } for ( ndx = 10; ndx < 100; ndx+=10) { ellipse( 500, 400, ndx, 100); ellipse( 500, 400, 100, ndx); } munmap( fb_mapped, mem_size); close( fb_fd); return 0; }
실행을 하면 아래와 같이 출력됩니다.
태그 : *그래픽 *타원 *ellipse