## 10. Circle

### 10.1. Stroked Circle

Midpoint circle algorithm.

I don't know where I found the code for the first algorithm, but it was too pointy at the compass coordinates. This one is slightly more expensive, but makes for a much smoother circle: https://iq.opengenus.org/bresenhams-circle-drawing-algorithm/

That ones a bit boxy, so I tried this one: https://zcsaha.github.io/computer-graphics/midpoint-circle-drawing-algorithm-in-c.html

I'm not great either. Kind of looks like a polygon when the radius is 16. We're keeping it at that for now.

<<funcdefs>>=
``````void btprnt_draw_circ(btprnt_region *r,
int cx, int cy,
int clr);``````
<<funcs>>=
``````static void circ_pixel(btprnt_region *r,
int cx, int cy,
int x, int y,
int clr)
{
btprnt_region_draw(r, cx - x, cy + y, clr);
btprnt_region_draw(r, cx + x, cy + y, clr);
btprnt_region_draw(r, cx - y, cy + x, clr);
btprnt_region_draw(r, cx + y, cy + x, clr);
btprnt_region_draw(r, cx + x, cy - y, clr);
btprnt_region_draw(r, cx - x, cy - y, clr);
btprnt_region_draw(r, cx + y, cy - x, clr);
btprnt_region_draw(r, cx - y, cy - x, clr);
}

void btprnt_draw_circ(btprnt_region *r,
int cx, int cy,
int clr)
{
int x;
int y;
int err;

x = 0;

circ_pixel(r, cx, cy, x, y, clr);

while (x < y) {
x++;

if (err < 0) {
err += 2 * x + 1;
} else {
y--;
err += 2 * (x - y) + 1;
}

circ_pixel(r, cx, cy, x, y, clr);
}
}``````

### 10.2. Filled Circle

`btprnt_draw_circ_filled` uses an adaptation of the midpoint circle algorithm to draw a filled circle. It has been adapated from `btprnt_draw_circ`.

<<funcdefs>>=
``````void btprnt_draw_circ_filled(btprnt_region *r,
int cx, int cy,
int clr);``````

<<funcs>>=
``````static void circ_line(btprnt_region *r,
int cx, int cy,
int x, int y,
int clr)
{
btprnt_draw_line(r,
cx - x, cy + y,
cx + x, cy + y,
clr);
btprnt_draw_line(r,
cx - y, cy + x,
cx + y, cy + x,
clr);
btprnt_draw_line(r,
cx + x, cy - y,
cx - x, cy - y,
clr);
btprnt_draw_line(r,
cx + y, cy - x,
cx - y, cy - x,
clr);

}

void btprnt_draw_circ_filled(btprnt_region *r,
int cx, int cy,
int clr)
{
int x;
int y;
int err;

x = 0;

circ_line(r, cx, cy, x, y, clr);

while (x < y) {
x++;

if (err < 0) {
err += 2 * x + 1;
} else {
y--;
err += 2 * (x - y) + 1;
}

circ_line(r, cx, cy, x, y, clr);
}
}``````

### 10.3. Thick Circle

`btprnt_draw_thickcirc` will draw a circle with a thick outline with a radius `rad`, thickness `thick`, and color `c`. This works like the normal midpoint circle algorithm, except that it draws filled circles instead of pixels.

<<funcdefs>>=
``````void btprnt_draw_thickcirc(btprnt_region *r,
int cx, int cy,
int clr);``````
<<funcs>>=
``````static void circ_dots(btprnt_region *r,
int cx, int cy,
int x, int y,
int clr, int thick)
{
btprnt_draw_circ_filled(r, cx - x, cy + y, thick, clr);
btprnt_draw_circ_filled(r, cx + x, cy + y, thick, clr);
btprnt_draw_circ_filled(r, cx - y, cy + x, thick, clr);
btprnt_draw_circ_filled(r, cx + y, cy + x, thick, clr);
btprnt_draw_circ_filled(r, cx + x, cy - y, thick, clr);
btprnt_draw_circ_filled(r, cx - x, cy - y, thick, clr);
btprnt_draw_circ_filled(r, cx + y, cy - x, thick, clr);
btprnt_draw_circ_filled(r, cx - y, cy - x, thick, clr);
}

void btprnt_draw_thickcirc(btprnt_region *r,
int cx, int cy,
int clr)
{
int x;
int y;
int err;

x = 0;

circ_dots(r, cx, cy, x, y, clr, thick);

while (x < y) {
x++;

if (err < 0) {
err += 2 * x + 1;
} else {
y--;
err += 2 * (x - y) + 1;
}

circ_dots(r, cx, cy, x, y, clr, thick);
}
}``````

prev | home | next