그래픽 & 멀티미디어
gx 라이브러리에 이번에는 원 그리기를 추가했습니다. 실은 원 그리기 함수를 넣지 않으려고 했습니다. 타원 그리기로도 원을 그릴 수 있기 때문이죠. 그러나 임베디드 보드가 조금 느리다라는 생각과 여기 강좌란에서 완벽한 그래픽 라이브러리를 만든다는 것 보다는 교육을 위한 필요도 있어서 추가하기로 했습니다.
역시 Device Context의 pen_color와 brush_color을 사용하여 테두리와 내부를 채웁니다. 한번의 원 그리기 루틴으로 내부의 선을 긋고 테두리에 점을 찍으면 빠르겠습니다만, 칼라 처리와 원의 테두리를 적용한다든지의 업그레이드를 위해 2번에 나누어 처리하겠습니다.
한번은 내부의 선을 긋고, 2번째 호출로 테두리 점을 찍습니다.
gx_circle()
| |||||||||
|
gx_circle()은 gx_rectangle와 마찬가지로 dc의 pen_color로 테두리를 그리고 brush_color로 내부 색을 채웁니다. 또한 pen_color 나 brush_color 가 clr_clear 일 경우 칠해지지 않습니다.
gx_circle()은 원을 그리는 함수 circle()을 호출하면서 내부의 색을 칠해주는 함수의 포인터와 외부의 테두리에 점을 찍은 함수의 포인터를 넘겨 줌으로써 하나의 원 그리기 루틴으로 두가지 작업을 처리합니다.
void gx_circle( dc_t *dc, int center_x, int center_y, int radius) { if ( 0 == radius) return; if ( clr_clear != dc->brush_color) circle( dc, center_x, center_y, radius, dc->brush_color, dc->hline); if ( clr_clear != dc->pen_color ) circle( dc, center_x, center_y, radius, dc->pen_color , circle_dot); }
gx_circle()에서 색상에 따라 두번의 호출을 하면서 선을 그리는 hline()과 circle_dot() 함수를 넘겨 줍니다.
static void circle( dc_t *dc, int center_x, int center_y, int radius, int color, void (*fun)( dc_t *dc, int, int, int, int)) { int coor_x; int coor_y; int p_value; coor_x = 0; coor_y = radius; p_value = 3 - 2 * radius; while ( coor_x < coor_y) { draw_circle( dc, center_x, center_y, coor_x, coor_y, color, fun); // 1/8의 원 출력 if ( p_value < 0) { p_value += 4 * coor_x +6; } else { p_value += 4 * ( coor_x -coor_y) +10; coor_y--; } coor_x++; } if ( coor_x == coor_y) draw_circle( dc, center_x, center_y, coor_x, coor_y, color, fun); // 1/8의 원 출력 }
원의 1/8 부분을 대칭으로 8개의 부분을 모두 그리는 루틴입니다.
static void draw_circle( dc_t *dc, int center_x, int center_y, int coor_x, int coor_y, int color, void (*fun)( dc_t *c, int, int, int, int)) { int y_dot; y_dot = center_y +coor_y; fun( dc, center_x-coor_x, center_x+coor_x, y_dot, color); y_dot = center_y -coor_y; fun( dc, center_x-coor_x, center_x+coor_x, y_dot, color); y_dot = center_y +coor_x; fun( dc, center_x-coor_y, center_x+coor_y, y_dot, color); y_dot = center_y -coor_x; fun( dc, center_x-coor_y, center_x+coor_y, y_dot, color); }
이 함수에서 실제로 원을 그리는 함수는 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_rectangle( dc_t *dc) { int coor_x, coor_y; int radius; static int ndx = 0; coor_x = rand() % dc->width; // 원의 좌표를 랜덤으로 구합니다. coor_y = rand() % dc->height; radius = rand() % 100; if ( !( ndx % 60)) gx_clear( dc, clr_black); // 매 호출 60번째 마다 // 검정색으로 Clear switch ( (ndx++ / 20) % 3) // 매번 20번째 마다 { // 테두리와 브러쉬 색상 처리를 바꿈 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_circle( dc, coor_x, coor_y, radius); usleep( 150 *1000); } void test( void) { 화면에 대한 Device Context를 구하고 성공하면 test_circle() 호출 } int main( void) { gx 라이브러리를 초기화하고 성공하면 test() 호출 }
프로그램을 실행하면 아래와 같이 계속 원을 출력하게 됩니다.
태그: *그래픽 *라이브러리 *그래픽라이브러리