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 rad,
                      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 rad,
                      int clr)
{
    int x;
    int y;
    int err;

    x = 0;
    y = rad;
    err = 1 - rad;

    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 rad,
                      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 rad,
                      int clr)
{
    int x;
    int y;
    int err;

    x = 0;
    y = rad;
    err = 1 - rad;

    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 rad, int thick,
                           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 rad, int thick,
                           int clr)
{
    int x;
    int y;
    int err;

    x = 0;
    y = rad;
    err = 1 - rad;

    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