그래픽 & 멀티미디어
글 수 111
2007.04.25 22:28:33 (*.239.53.178)
40297
원을 알아보았으니까 이번에는 타원을 알아봐야 갰지요. 역시 정수 계산만으로 타원을 그리는 방법입니다만 이렇게 실수를 사용하지 않고 타원을 그린다는 자체가 참 신기하기만 합니다.
한가지 아래의 코드는 제가 아주 오래전에 어디서 구한 코드입니다. 그런데 아쉽게도 코드를 구해놓고 정작 출처를 잊어버렸네요. 제 기억으로는 아래의 코드는 브레슨햄의 알고리듬을 이용한 것은 아닙니다. 그러나 나눗셈이 있더라도 루프 밖에 있고, 작업이 많은 루프 안에서는 역시 정수 덧셈과 뺄셈만 있습니다.
구현한 함수는 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


