## 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