Circle Drawing (픽셀 단위 원 그리기)
2011. 3. 20. 12:01
알고리즘
(x - r)^2 + (y - r)^2 = r^2
알고리즘은 간단하다. 위와 같은 원의 공식을 사용한다.
원의 모양을 예측해 보면 (r, r)의 중심점을 가지는 반지름이 r인 원이 그려진다.
이 포스트에서는 반지름 이내의 범위의 어떤 좌표 (x, y)에 있는 점은 검은색 상자 (■)로 표시하고,
그렇지 않은 점은 빈 상자(□)로 표시할 생각이다.
간단히 생각해 보면 이중 반복문을 돌려서
삼항연산자든 if문이든 걸어서 범위 체크만 해주면 끝이라고 생각 할 수 있다.
하지만 실제로 그를 토대로 그려보면, 뭔가 좌우 대칭이 잘 맞지 않는다.
접근 방법
텍스트만 가지고 원을 그리려면, 픽셀 단위의 드로잉을 생각해야만 한다.
어떤 도장이 있다. 도장은 가로세로 1cm의 크기를 갖는 정사각형 모양을 찍어낸다.
이 도장을 가지고 반지름이 7cm인 원을 그린다고 생각하자.
원의 중심점에 빨간 도장을 찍어버리면, 원의 반지름을 표현하기 위해 8개의 도장을 찍게 된다.
원 전체를 그리게 되면 한 줄에 15개의 도장을 찍어야 한다.
반지름 7cm의 원을 그려야 하는데, 결론적으로는 지름 15cm인 원이 탄생하게 되는 것이다.
만약 반복문을 조금 고쳐서 어찌됐든 14cm가 되게 한다면, 어느 한 쪽은 잘려나가게 되고 비대칭적인 원이 탄생한다.
게다가, 동서남북에는 항상 1개의 도장이 찍히게 된다.
원의 형태는 나오지만 우리가 원하는 결과는 아니다.
이러한 결과는 우리가
r * r > (x - r)*(x - r) + (y - r)*(y - r)
같은 비교식을 사용했을때 얻게 된다.
따라서 우리는 어긋나버린 핀트를 조금 맞춰줄 필요가 있다. 방법은 간단하다.
픽셀을 각각 0.5cm씩 어긋난 위치에서 가져오는 것이다.
비교식은 다음과 같이 변화한다.
r * r > (x + 0.5 - r)*(x + 0.5 - r) + (y + 0.5 - r)*(y + 0.5 - r)
이제 14 x 14 개의 픽셀로 반지름 7의 원을 만드는것이 가능하다.
코드
#include <stdio.h>
void main() {
int i,j,u;
FILE *f;
printf("<Circle Drawing>\nInput a integer number of radius of circle.> ");
scanf_s("%d",&u,sizeof(int));
fopen_s(&f,"circle.txt","w");
for(i=0;i<u*2;i++){
for(j=0;j<u*2;j++){
(u*u > (i+0.5-u)*(i+0.5-u) + (j+0.5-u)*(j+0.5-u))? fprintf(f,"■") : fprintf(f,"□");
}
fprintf(f,"\n");
}
fclose(f);
}
결과
숫자를 입력받아서 circle.txt로 출력한다.
circle.txt에는 입력한 반지름의 크기를 가진 원이 그려져 있을 것이다.
메모장을 이용하는 경우, 원이 너무 크면 '자동 줄바꿈'을 해제해야 한다.
반지름을 21로 입력해서 얻은 결과는 아래와 같다.
숫자를 입력받아서 circle.txt로 출력한다.
circle.txt에는 입력한 반지름의 크기를 가진 원이 그려져 있을 것이다.
메모장을 이용하는 경우, 원이 너무 크면 '자동 줄바꿈'을 해제해야 한다.
반지름을 21로 입력해서 얻은 결과는 아래와 같다.
□□□□□□□□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□
□□□□□□□□□□□□□■■■■■■■■■■■■■■■■□□□□□□□□□□□□□
□□□□□□□□□□□■■■■■■■■■■■■■■■■■■■■□□□□□□□□□□□
□□□□□□□□□■■■■■■■■■■■■■■■■■■■■■■■■□□□□□□□□□
□□□□□□□□■■■■■■■■■■■■■■■■■■■■■■■■■■□□□□□□□□
□□□□□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□□□□□
□□□□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□□□□
□□□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□□□
□□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□□
□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□
□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□
□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□
□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□
□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□
□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□
□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□
□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□
□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□
□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□
□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□
□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□
□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□
□□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□□
□□□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□□□
□□□□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□□□□
□□□□□□□■■■■■■■■■■■■■■■■■■■■■■■■■■■■□□□□□□□
□□□□□□□□■■■■■■■■■■■■■■■■■■■■■■■■■■□□□□□□□□
□□□□□□□□□■■■■■■■■■■■■■■■■■■■■■■■■□□□□□□□□□
□□□□□□□□□□□■■■■■■■■■■■■■■■■■■■■□□□□□□□□□□□
□□□□□□□□□□□□□■■■■■■■■■■■■■■■■□□□□□□□□□□□□□
□□□□□□□□□□□□□□□□■■■■■■■■■■□□□□□□□□□□□□□□□□
문제점
현재 프로그램은 반지름을 입력받기 때문에, 지름이 홀수인 원을 그려낼 수 없게 되어있다.
지름이 홀수인 원을 그리기 위해서는 어떻게 코딩을 해야할까?
간단히 몇 가지만 수정하면 된다.
#include <stdio.h>
void main() {
int i,j,u;
FILE *f;
printf("<Circle Drawing>\nInput a integer number of diameter of circle.> ");
scanf_s("%d",&u,sizeof(int));
fopen_s(&f,"circle.txt","w");
for(i=0;i<u;i++){
for(j=0;j<u;j++){
(u*u/4.0 > (i+0.5-u/2.0)*(i+0.5-u/2.0) + (j+0.5-u/2.0)*(j+0.5-u/2.0))? fprintf(f,"■") : fprintf(f,"□");
}
fprintf(f,"\n");
}
fclose(f);
}
생각해 봐야할 문제
타원을 그리려면 어떻게 해야할 것인가?
테두리만 있는 원을 그리려면 어떻게 해야 할 것인가?
직접 생각해 보기 바란다.
다운로드
위 프로그램을 다운 받아 실행하면, 명령 프롬프트가 뜨고 반지름을 입력하면 같은 폴더에 circle.txt가 생성된다.
지름을 입력받아 원을 그려주는 프로그램에 대해서는 스스로 해보기 바란다.