8. Lines

8.1. Horizontal Line

A horizontal line can be drawn with btprnt_draw_hline.

<<funcdefs>>=
void btprnt_draw_hline(btprnt_region *r,
                       int x, int y,
                       int sz, int clr);
<<funcs>>=
void btprnt_draw_hline(btprnt_region *r,
                       int x, int y,
                       int sz, int clr)
{
    int n;

    for (n = 0; n < sz; n++) {
        btprnt_region_draw(r, x + n, y, clr);
    }
}

8.2. Vertical Line

A horizontal line can be drawn with btprnt_draw_vline.

<<funcdefs>>=
void btprnt_draw_vline(btprnt_region *r,
                       int x, int y,
                       int sz, int clr);
<<funcs>>=
void btprnt_draw_vline(btprnt_region *r,
                       int x, int y,
                       int sz, int clr)
{
    int n;

    for (n = 0; n < sz; n++) {
        btprnt_region_draw(r, x, y + n, clr);
    }
}

8.3. Regular Line

Bresenham line algorithm.

<<funcdefs>>=
void btprnt_draw_line(btprnt_region *reg,
                      int x0, int y0,
                      int x1, int y1,
                      int clr);
<<funcs>>=
static void swap(int *a, int *b)
{
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}

void btprnt_draw_line(btprnt_region *reg,
                      int x0, int y0,
                      int x1, int y1,
                      int clr)
{
    int x, y;
    int dx, dy;
    int derror2;
    int error2;
    char steep = 0;

    if (abs(x0 - x1) < abs(y0 - y1)) {
        swap(&x0, &y0);
        swap(&x1, &y1);
        steep = 1;
    }

    if (x0 > x1) {
        swap(&x0, &x1);
        swap(&y0, &y1);
    }

    dx = x1 - x0;
    dy = y1 - y0;
    derror2 = abs(dy) * 2;
    error2 = 0;
    y = y0;

    for (x = x0; x < x1; x++) {
        if (steep) {
            btprnt_region_draw(reg, y, x, clr);
        } else {
            btprnt_region_draw(reg, x, y, clr);
        }
        error2 += derror2;
        if (error2 > dx) {
            y += (y1 > y0 ? 1 : -1);
            error2 -= dx * 2;
        }
    }
}

8.4. Thick Line

btprnt_draw_thickline draws a thick line. This is a modification of the Bresenham algorithm. Instead of pixels, little circles are drawn.

<<funcdefs>>=
void btprnt_draw_thickline(btprnt_region *reg,
                           int x0, int y0,
                           int x1, int y1,
                           int thick,
                           int clr);
<<funcs>>=
void btprnt_draw_thickline(btprnt_region *reg,
                           int x0, int y0,
                           int x1, int y1,
                           int thick,
                           int clr)
{
    int x, y;
    int dx, dy;
    int derror2;
    int error2;
    char steep = 0;

    if (abs(x0 - x1) < abs(y0 - y1)) {
        swap(&x0, &y0);
        swap(&x1, &y1);
        steep = 1;
    }

    if (x0 > x1) {
        swap(&x0, &x1);
        swap(&y0, &y1);
    }

    dx = x1 - x0;
    dy = y1 - y0;
    derror2 = abs(dy) * 2;
    error2 = 0;
    y = y0;

    for (x = x0; x < x1; x++) {
        if (steep) {
            btprnt_draw_circ_filled(reg, y, x, thick, clr);
        } else {
            btprnt_draw_circ_filled(reg, x, y, thick, clr);
        }
        error2 += derror2;
        if (error2 > dx) {
            y += (y1 > y0 ? 1 : -1);
            error2 -= dx * 2;
        }
    }
}

8.5. Slope Line

Draws N pixel steps with a specified slope, and returns the last coordinate (if the values are not NULL).

This is created with the intention of facilitating generative pixel art.

<<funcdefs>>=
void btprnt_draw_slopeline(btprnt_region *r,
                           int xstart,
                           int ystart,
                           int xslp,
                           int yslp,
                           int nsteps,
                           int clr,
                           int *xlast,
                           int *ylast);
<<funcs>>=
void btprnt_draw_slopeline(btprnt_region *r,
                           int xstart,
                           int ystart,
                           int xslp,
                           int yslp,
                           int nsteps,
                           int clr,
                           int *xlast,
                           int *ylast)
{
    int c;
    int xp, yp;
    int ydir, xdir;

    c = nsteps;

    xp = xstart;
    yp = ystart;

    xdir = (xslp < 0) ? -1 : 1;
    ydir = (yslp < 0) ? -1 : 1;

    xslp = abs(xslp);
    yslp = abs(yslp);

    while (c > 0) {
        int x, y;
        for (x = 0; x < xslp; x++) {
            btprnt_region_draw(r, xp, yp, clr);
            c--;
            if (c <= 0) break;
            xp += xdir;
        }

        if (c <= 0) break;

        for (y = 0; y < yslp; y++) {
            if (y > 0) {
                btprnt_region_draw(r, xp - xdir, yp, clr);
                c--;
                if (c <= 0) break;
            }
            yp += ydir;
        }

    }

    if (xlast != NULL) *xlast = xp;
    if (ylast != NULL) *ylast = yp;
}

8.6. TODO Pattern Line

Draws a horizontal using a pattern for color. This will be the base for pattern-filled shapes.



prev | home | next