Bresenham's Midpoint Circle Algorithm : https://en.wikipedia.org/wiki/Midpoint_circle_algorithm




아는 형이 코드를 봐달라 해서 잠깐 봤다.


#include <stdio.h>
#include <stdlib.h>

typedef struct COLOR {
	unsigned char r;
	unsigned char g;
	unsigned char b;
} COLOR;

int w = 0;
int h = 0;
int red = 0, green = 0, blue = 0;
int red_f = 0, green_f = 0, blue_f = 0;
COLOR* image;

void pixel(int x, int y) {
	image[x * w + y].r = red;
	image[x * w + y].g = green;
	image[x * w + y].b = blue;
}

void pixel_f(int x, int y) {
	image[x * w + y].r = red_f;
	image[x * w + y].g = green_f;
	image[x * w + y].b = blue_f;
}

void circle_boundary(int x0, int y0, int x, int y) {
	pixel(x0 + x, y0 - y);
	pixel(x0 + x, y0 + y);
	pixel(x0 - x, y0 + y);
	pixel(x0 - x, y0 - y);
	pixel(x0 + y, y0 - x);
	pixel(x0 + y, y0 + x);
	pixel(x0 - y, y0 + x);
	pixel(x0 - y, y0 - x);
}
void circle_filled(int x0, int y0, int x, int y) {
	pixel_f(x0 + x, y0 + y);
	pixel_f(x0 - x, y0 + y);
	pixel_f(x0 + x, y0 - y);
	pixel_f(x0 - x, y0 - y);
	pixel_f(x0 + y, y0 + x);
	pixel_f(x0 + y, y0 - x);
	pixel_f(x0 - y, y0 + x);
	pixel_f(x0 - y, y0 - x);
}

int main() {
	int x0, y0, r, x, y, d, y_f;
	printf("Enter Image Size (Width, Height) : ");
	scanf("%d%d", &w, &h);
	printf("Enter Center Position (x0, y0) : ");
	scanf("%d%d", &x0, &y0);
	printf("Enter Radius (r) : ");
	scanf("%d", &r);
	printf("Enter Boundary Color (R, G, B) : ");
	scanf("%d%d%d", &red, &green, &blue);
	printf("Enter Fill Color (R, G, B) : ");
	scanf("%d%d%d", &red_f, &green_f, &blue_f);

	image = new COLOR[h * w];
	d = 3 - (2 * r);
	x = 0;
	y = r;
	y_f = y - 1;

	//Initializing Background as white color
	for (int i = 0; i < h; ++i) {
		for (int j = 0; j < w; ++j) {
			image[i * w + j].r = 255;
			image[i * w + j].g = 255;
			image[i * w + j].b = 255;
		}
	}
	circle_boundary(x0, y0, x, y);
	while (x < y) {
		if (d < 0) {
			x = x + 1;
			d = d + (4 * x) + 6;
			circle_boundary(x0, y0, x, y);
		}
		else {
			x = x + 1;
			y = y - 1;
			d = d + (4 * (x - y)) + 10;
			circle_boundary(x0, y0, x, y);
		}
	}
	//Save image data as *.ppm file
	FILE *fp = fopen("result.ppm", "wb");
	fprintf(fp, "P6\n");
	fprintf(fp, "%d\n", w);
	fprintf(fp, "%d\n", h);
	fprintf(fp, "%d\n", 255);
	fwrite(image, sizeof(COLOR), h * w, fp);
	fclose(fp);

	free(image);

	return 0;
}



이렇게 원이 나오는데 내부를 채우는게 과제라고 했다.


어떻게 채워줄까 했더니 안에 원을 무수히 많이 그려보자고 한다.


그러면 안이 색으로 가득 차지 않겠냐고 한다.


그래서 안에 무수히 많은 원을 그려보기로 했다.


	for (int i = 0; i < r; ++i) {
		int x = 0;
		int t = i;
		int y = t;
		int d = 3 - (2 * t);
		circle_filled(x0, y0, x, y);
		while (x < y) {
			if (d < 0) {
				x = x + 1;
				d = d + (4 * x) + 6;
				circle_filled(x0, y0, x, y);
			}
			else {
				x = x + 1;
				y = y - 1;
				d = d + (4 * (x - y)) + 10;
				circle_filled(x0, y0, x, y);
			}
		}
	}

모양은 이쁘지만 당연히 이렇게 채우면 안된다. 


픽셀로 그리기 때문에 여백이 계속 일정한 간격으로 남게 된다.


군대 가기 전에 배운 Bresenham 알고리즘이 뭐였는지 기억은 안나고 무식하게 원을 채워보았다.

방법은 간단하다. 그냥 테두리와 테두리 사이를 쭉 그어버리면 된다.



위의 코드에서는 가로, 세로 두 번 그었지만 한 번만 그어도 문제 없이 나타난다.


먼저 내부를 색칠 한 후, 테두리를 그려주는 방식이다. 코드는 되도록 넘겨받았을 당시의 형태를 유지하였다.



보통 사람은 테두리를 그리고 나서 내부를 칠하는 데 이 코드는 반대로 행하는 그림이다. 


완전 엉터리다.


원이니까 이렇게 가능했지, 복잡한 도형은 이렇게 하면 안된다.

+ Recent posts