diff options
-rw-r--r-- | LICENSE | 2 | ||||
-rw-r--r-- | common.h | 10 | ||||
-rw-r--r-- | draw_linear_bezier_reference.c | 152 | ||||
-rw-r--r-- | equations.c | 2 | ||||
-rw-r--r-- | lines.c | 4 | ||||
-rw-r--r-- | rtgrpblib_draw_cubic_bezier.c | 4 | ||||
-rw-r--r-- | rtgrpblib_draw_linear_bezier.c | 67 | ||||
-rw-r--r-- | rtgrpblib_draw_quadratic_bezier.c | 206 |
8 files changed, 337 insertions, 110 deletions
@@ -1,6 +1,6 @@ ISC License -© 2023 Mattias Andrée <maandree@kth.se> +© 2023 Mattias Andrée <m@maandree.se> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -145,12 +145,6 @@ tolerant_eq(double a, double b) return iszeroish((a - b) / 100.0); } -static inline int -intolerant_eq(double a, double b) -{ - return fabs(a - b) < 1e-11; -} - # define ASSERT(ASSERTION)\ do {\ if (!(ASSERTION)) {\ @@ -159,8 +153,8 @@ intolerant_eq(double a, double b) }\ } while (0) -# if 0 -static void +# if 1 +static inline void print_raster(const RASTER *r) { size_t y, x; fprintf(stderr, "\nOutline (area)\n"); diff --git a/draw_linear_bezier_reference.c b/draw_linear_bezier_reference.c index dbfb87f..b7dab11 100644 --- a/draw_linear_bezier_reference.c +++ b/draw_linear_bezier_reference.c @@ -14,86 +14,94 @@ */ -void -draw_linear_bezier_reference(RASTER *restrict raster, double x1, double y1, double x2, double y2) +static void +draw_cell(RASTER *restrict raster, double x1, double y1, double x2, double y2, double dx, double dy, + double cxmin, double cxmax, double rxmin, double rxmax, double rymin, double rymax, ssize_t x, size_t cellY) { - double dx = x2 - x1; - double dy = y2 - y1; - int xdir = SIGNUM(dx); - int ydir = SIGNUM(dy); - double kx = dx / dy; - double ky = dy / dx; - double prevX, prevY, x, y, cx, cy, h2x, h2y; - double xfloor, yfloor; - ssize_t cellX, cellY; + double cy1, cy2, ydir = (double)SIGNUM(dy); + double rightedge, opposite, midadjacent; size_t cell; - prevX = x1; - prevY = y1; - - for (; prevX != x2 || prevY != y2; prevX = x, prevY = y) { - /* Find next vertical and next hozitonal grid line */ - x = xdir < 0 ? floor(prevX) : xdir > 0 ? ceil(prevX) : prevX; - y = ydir < 0 ? floor(prevY) : ydir > 0 ? ceil(prevY) : prevY; - x = iszeroish(x - prevX) ? x + xdir : x; - y = iszeroish(y - prevY) ? y + ydir : y; - - /* Limit to the extend of the drawn line segment */ - if ((xdir < 0 && x < x2) || (xdir > 0 && x > x2)) - x = x2; - if ((ydir < 0 && y < y2) || (ydir > 0 && y > y2)) - y = y2; - - /* Find next cell edge */ - if (xdir && ydir) { - cy = y1 + (x - x1) * ky; - cx = x1 + (y - y1) * kx; - h2x = (cy - prevY) * (cy - prevY) + (x - prevX) * (x - prevX); - h2y = (cx - prevX) * (cx - prevX) + (y - prevY) * (y - prevY); - if (h2x < h2y) - y = cy; - else - x = cx; - - /* Make sure loop will exit when we reach the end */ - if ((xdir < 0 && x <= x2) || (xdir > 0 && x >= x2) || - (ydir < 0 && y <= y2) || (ydir > 0 && y >= y2)) { - x = x2; - y = y2; - } - } + rightedge = cxmax; + cxmin = fmax(cxmin, rxmin); + cxmax = fmin(cxmax, rxmax); + cy1 = dx ? y1 + (cxmin - x1) * dy / dx : y1; + cy2 = dx ? y2 + (cxmax - x2) * dy / dx : y2; + cy1 = fmin(fmax(cy1, rymin), rymax); + cy2 = fmin(fmax(cy2, rymin), rymax); - /* Select cell to draw in */ - xfloor = xdir >= 0 ? floor(prevX) : floor(x); - yfloor = ydir >= 0 ? floor(prevY) : floor(y); - cellX = (ssize_t)xfloor; - cellY = (ssize_t)yfloor; + opposite = ydir * fabs(cy2 - cy1); + midadjacent = (cxmin + cxmax) / 2.0; - /* Do not draw if above or below the raster */ - if (cellY < 0 || (size_t)cellY >= raster->height) - continue; + if (x < 0) { + raster->cells[cellY].opposite_coverage += opposite; + raster->cells[cellY].cell_coverage += opposite; + } else if ((size_t)x >= raster->width) { + cell = cellY + (raster->width - 1); + raster->cells[cell].opposite_coverage += opposite; + } else { + cell = cellY + (size_t)x; + raster->cells[cell].opposite_coverage += opposite; + raster->cells[cell].cell_coverage += opposite * fabs(rightedge - midadjacent); + } +} - if (cellX < 0) { - /* Draw on first column in raster of outside of raster on the left side, - * with full horizontal coverage, `.opposite_coverage` one the actual - * cell (outside of the raster) will contribute to the first column's - * `.cell_coverage` */ - cell = (size_t)cellY * raster->width; - raster->cells[cell].opposite_coverage += y - prevY; - raster->cells[cell].cell_coverage += y - prevY; +void +draw_linear_bezier_reference(RASTER *restrict raster, double x1, double y1, double x2, double y2) +{ + ssize_t iwidth = (ssize_t)raster->width; + double width = (double)raster->width; + double height = (double)raster->height; + double dx = x2 - x1; + double dy = y2 - y1; + double fymin = fmin(fmax(fmin(y1, y2), 0.0), height); + double fymax = fmin(fmax(fmax(y1, y2), 0.0), height); + double floor_fymin = floor(fymin); + double ceil_fymax = ceil(fymax); + size_t ymin = (size_t)floor_fymin; + size_t ymax = (size_t)ceil_fymax; + size_t y, cellY; + double rowx1, rowx2; + double rxmin, rxmax, floor_rxmin; + double rymax, rymin, ceil_rxmax; + ssize_t x, xmin, xmax, xmin_cropped, xmax_cropped; + double cxmin, cxmax; - } else if ((size_t)cellX >= raster->width) { - /* If outside of the raster, on the right side, add to the last - * columns contributions to the next column, so that the ink level - * balances out to zero */ - cell = (size_t)cellY * raster->width + (raster->width - 1); - raster->cells[cell].opposite_coverage += y - prevY; + ymax += (size_t)(ymax == ymin); + for (y = ymin; y < ymax; y++) { + rymin = (double)y; + rymax = (double)y + 1.0; + rymin = fmax(rymin, fymin); + rymax = fmin(rymax, fymax); + rowx1 = dy ? x1 + (rymin - y1) * dx / dy : x1; + rowx2 = dy ? x2 + (rymax - y2) * dx / dy : x2; + rxmin = fmin(rowx1, rowx2); + rxmax = fmax(rowx1, rowx2); + cellY = y * raster->width; - } else { - /* If inside the raster, just draw the line */ - cell = (size_t)cellY * raster->width + (size_t)cellX; - raster->cells[cell].opposite_coverage += y - prevY; - raster->cells[cell].cell_coverage += (y - prevY) * fabs(xfloor + 1.0 - (x + prevX) / 2.0); + floor_rxmin = floor(rxmin); + ceil_rxmax = ceil(rxmax); + xmin = (ssize_t)floor_rxmin; + xmax = (ssize_t)ceil_rxmax; + xmax += (ssize_t)(xmax == xmin); + xmin_cropped = xmin; + xmax_cropped = xmax; + if (xmin < 0.0) { + cxmin = (double)xmin; + cxmax = xmax < 0 ? (double)(xmax + 1) : 0.0; + draw_cell(raster, x1, y1, x2, y2, dx, dy, cxmin, cxmax, rxmin, rxmax, rymin, rymax, xmin, cellY); + xmin_cropped = 0; + } + if (xmax > iwidth) { + cxmin = fmax(floor_rxmin, width); + cxmax = (double)xmax; + draw_cell(raster, x1, y1, x2, y2, dx, dy, cxmin, cxmax, rxmin, rxmax, rymin, rymax, (ssize_t)cxmin, cellY); + xmax_cropped = iwidth; + } + for (x = xmin_cropped; x < xmax_cropped; x++) { + cxmin = (double)x; + cxmax = (double)x + 1.0; + draw_cell(raster, x1, y1, x2, y2, dx, dy, cxmin, cxmax, rxmin, rxmax, rymin, rymax, x, cellY); } } } diff --git a/equations.c b/equations.c index 571fc26..2cf8bc9 100644 --- a/equations.c +++ b/equations.c @@ -302,6 +302,8 @@ check_cubic(double r1, double i1, double r2, double i2, double r3, double i3, do for (i = 0; i < sizeof(found) / sizeof(*found); i++) found[i] = (i >= nexpected || expected[i] < 0.0 + TOLERANCE || expected[i] > 1.0 - TOLERANCE); if (!nexpected) { + if (!ngot) /* FIXME */ + fprintf(stderr, "%lg, %lg, %lg, %lg, %lg, %lg, %lg, %i\n", r1, i1, r2, i2, r3, i3, k, strict_real); ASSERT(!ngot); return; } @@ -242,8 +242,8 @@ check_against_reference(double x1, double y1, double x2, double y2) draw_linear_bezier_reference(refraster, x1, y1, x2, y2); alarm(0); for (i = 0; i < 100; i++) { - ASSERT(intolerant_eq(raster->cells[i].cell_coverage, refraster->cells[i].cell_coverage)); - ASSERT(intolerant_eq(raster->cells[i].opposite_coverage, refraster->cells[i].opposite_coverage)); + ASSERT(eq(raster->cells[i].cell_coverage, refraster->cells[i].cell_coverage)); + ASSERT(eq(raster->cells[i].opposite_coverage, refraster->cells[i].opposite_coverage)); } } diff --git a/rtgrpblib_draw_cubic_bezier.c b/rtgrpblib_draw_cubic_bezier.c index c68ad88..ca5f40b 100644 --- a/rtgrpblib_draw_cubic_bezier.c +++ b/rtgrpblib_draw_cubic_bezier.c @@ -165,12 +165,12 @@ rtgrpblib_draw_cubic_bezier(RASTER *restrict raster, double x1, double y1, doubl /* Remove any segments above or below the raster */ y = evaluate_cubic_bezier(t, y1, y2, y3, y4); - if (y < 0 || y >= (double)raster->height) + if (y < 0 || y > (double)raster->height) continue; /* If the segment is inside the raster, draw it, */ x = evaluate_cubic_bezier(t, x1, x2, x3, x4); - if (0 <= x && x < (double)raster->width) { + if (0 <= x && x <= (double)raster->width) { draw_bounded_cubic_bezier(raster, x1, y1, x2, y2, x3, y3, x4, y4, t1, t2); continue; } diff --git a/rtgrpblib_draw_linear_bezier.c b/rtgrpblib_draw_linear_bezier.c index bf9d41e..a2af58f 100644 --- a/rtgrpblib_draw_linear_bezier.c +++ b/rtgrpblib_draw_linear_bezier.c @@ -127,24 +127,65 @@ static RASTER *raster; static RASTER *refraster; +#ifdef ROWWISE_RESET_INKLEVEL static void -check_draw_linear_bezier(double x1, double y1, double x2, double y2) +draw_right_edge_shadow(double x1, double y1, double x2, double y2) +{ + if (raster->draftness <= 0) + return; + + if (x1 >= 10.0 && x2 >= 10.0) { + draw_linear_bezier_reference(raster, x1, y1, x2, y2); + + } else if (x1 >= 10.0) { + y2 = y2 + (10.0 - x2) * (y2 - y1) / (x2 - x1); + x2 = 10.0; + draw_linear_bezier_reference(raster, x1, y1, x2, y2); + + } else if (x2 >= 10.0) { + y1 = y1 + (10.0 - x1) * (y2 - y1) / (x2 - x1); + x1 = 10.0; + draw_linear_bezier_reference(raster, x1, y1, x2, y2); + } +} +#endif + + +static void +proper_check_draw_linear_bezier(double x1, double y1, double x2, double y2) { size_t i; + alarm(5); rtgrpblib_draw_linear_bezier(raster, x1, y1, x2, y2); +#ifdef ROWWISE_RESET_INKLEVEL + draw_right_edge_shadow(x1, y1, x2, y2); +#endif + alarm(5); draw_linear_bezier_reference(refraster, x1, y1, x2, y2); + alarm(0); + for (i = 0; i < 100; i++) { - ASSERT(intolerant_eq(raster->cells[i].cell_coverage, refraster->cells[i].cell_coverage)); - ASSERT(intolerant_eq(raster->cells[i].opposite_coverage, refraster->cells[i].opposite_coverage)); + ASSERT(eq(raster->cells[i].cell_coverage, refraster->cells[i].cell_coverage)); + ASSERT(eq(raster->cells[i].opposite_coverage, refraster->cells[i].opposite_coverage)); } rtgrpblib_reset_raster(raster, 10, 10); rtgrpblib_reset_raster(refraster, 10, 10); } +static void +check_draw_linear_bezier(double x1, double y1, double x2, double y2) +{ + proper_check_draw_linear_bezier(floor(x1), floor(y1), floor(x2), floor(y2)); + proper_check_draw_linear_bezier(floor(x1), y1, floor(x2), y2); + proper_check_draw_linear_bezier(x1, floor(y1), x2, floor(y2)); + proper_check_draw_linear_bezier(x1, y1, x2, y2); +} + + static double frand(double a, double b) { @@ -169,26 +210,26 @@ main(void) ASSERT(refraster); srand((unsigned)(uintptr_t)raster); - for (i = 0; i < 10000UL; i++) { -#ifndef ROWWISE_RESET_INKLEVEL + for (i = 0; i < 50000UL; i++) { x1 = frand(-5, 15); y1 = frand(-5, 15); x2 = frand(-5, 15); y2 = frand(-5, 15); -#else - /* TODO add tests the support higher upper bound */ - x1 = frand(0, 10); /* TODO fix lower bound */ - y1 = frand(-5, 15); - x2 = frand(-5, 10); - y2 = frand(-5, 15); -#endif check_draw_linear_bezier(x1, y1, x2, y2); check_draw_linear_bezier(x1, x1, x2, x2); + check_draw_linear_bezier(x1, y1, x2, y1); check_draw_linear_bezier(x1, x2, x2, x1); + check_draw_linear_bezier(x1, y1, x1, y2); + check_draw_linear_bezier(x1, x1, x1, x1); + raster->draftness = -1; + check_draw_linear_bezier(x1, y1, x2, y2); + check_draw_linear_bezier(x1, x1, x2, x2); check_draw_linear_bezier(x1, y1, x2, y1); + check_draw_linear_bezier(x1, x2, x2, x1); check_draw_linear_bezier(x1, y1, x1, y2); - /* TODO test with zero draftness */ + check_draw_linear_bezier(x1, x1, x1, x1); + raster->draftness = 0.5; } free(raster); diff --git a/rtgrpblib_draw_quadratic_bezier.c b/rtgrpblib_draw_quadratic_bezier.c index 8aae11e..e2202c6 100644 --- a/rtgrpblib_draw_quadratic_bezier.c +++ b/rtgrpblib_draw_quadratic_bezier.c @@ -90,23 +90,22 @@ rtgrpblib_draw_quadratic_bezier(RASTER *restrict raster, double x1, double y1, size_t nts = 0; size_t i; -#ifdef TODO /* untested */ /* Can we downgrade the curve to a linear Bézier curve? * * (y2 - y1)/(x2 - x1) = (y3 - y2)/(x3 - x2) = (y3 - y1)/(x3 - x1) * (y2 - y1)/(x2 - x1) = (y3 - y2)/(x3 - x2) * (y2 - y1)(x3 - x2) = (y3 - y2)(x2 - x1) */ - if ((y3 - y1) * (x3 - x2) == (y3 - y2) * (x2 - x1)) { - if (x1 <= x2 && x2 <= x3 && y1 <= y2 && y2 <= y3) - rtgrpblib_draw_linear_bezier(raster, x1, y1, x3, y3); - else if (x1 <= x3 && x3 <= x2 && y1 <= y3 && y3 <= y2) - rtgrpblib_draw_linear_bezier(raster, x1, y1, x2, y2); - else - rtgrpblib_draw_linear_bezier(raster, x2, y2, x3, y3); + if ((y2 - y1) * (x3 - x2) == (y3 - y2) * (x2 - x1)) { + /* Drawing (x1, y1)--(x2, y2) plus (x2, y2)--(x3, y3) + * is equivalent to drawing (x1, y1)--(x3, y3) because + * the result is signed and if (x2, y2) is outside the + * (x1, y1)--(x3, y3) line (x2, y2)--(x3, y3) erases + * the part that (x1, y1)--(x2, y2) extends to + * (x1, y1)--(x3, y3) */ + rtgrpblib_draw_linear_bezier(raster, x1, y1, x3, y3); return; } -#endif /* Beginning and end of curve */ ts[nts++] = 0.0; @@ -126,12 +125,12 @@ rtgrpblib_draw_quadratic_bezier(RASTER *restrict raster, double x1, double y1, /* Remove any segments above or below the raster */ y = evaluate_quadratic_bezier(t, y1, y2, y3); - if (y < 0 || y >= (double)raster->height) + if (y < 0 || y > (double)raster->height) continue; /* If the segment is inside the raster, draw it, */ x = evaluate_quadratic_bezier(t, x1, x2, x3); - if (0 <= x && x < (double)raster->width) { + if (0 <= x && x <= (double)raster->width) { draw_bounded_quadratic_bezier(raster, x1, y1, x2, y2, x3, y3, t1, t2); continue; } @@ -157,10 +156,193 @@ rtgrpblib_draw_quadratic_bezier(RASTER *restrict raster, double x1, double y1, #else +static RASTER *raster; +static RASTER *refraster; + + +static double +frand(double a, double b) +{ + int i = rand(); + double f = (double)i / (double)RAND_MAX; + double max = fmax(a, b); + double min = fmin(a, b); + return fma(f, max - min, min); +} + + +static void +check_line(double x1, double y1, double x2, double y2, double x3, double y3, int exact) +{ + size_t i; + + alarm(5); + rtgrpblib_draw_quadratic_bezier(raster, x1, y1, x2, y2, x3, y3); + + alarm(5); + rtgrpblib_draw_linear_bezier(refraster, x1, y1, x3, y3); + + alarm(0); + + if (exact) { + ASSERT(!memcmp(raster->cells, refraster->cells, 100 * sizeof(*raster->cells))); + } else { + for (i = 0; i < 100; i++) { + if (!eq(raster->cells[i].cell_coverage, refraster->cells[i].cell_coverage)) + fprintf(stderr, "c%02zu: %la ref: %la; diff: %lg=%la (tol: %la)\n", i, raster->cells[i].cell_coverage, refraster->cells[i].cell_coverage, refraster->cells[i].cell_coverage - raster->cells[i].cell_coverage, refraster->cells[i].cell_coverage - raster->cells[i].cell_coverage, TOLERANCE); + if (!eq(raster->cells[i].opposite_coverage, refraster->cells[i].opposite_coverage)) + fprintf(stderr, "o%02zu: %la ref: %la; diff: %lg=%la (tol: %la)\n", i, raster->cells[i].opposite_coverage, refraster->cells[i].opposite_coverage, raster->cells[i].opposite_coverage - refraster->cells[i].opposite_coverage, raster->cells[i].opposite_coverage - refraster->cells[i].opposite_coverage, TOLERANCE); + } + for (i = 0; i < 100; i++) { + if (!eq(raster->cells[i].cell_coverage, refraster->cells[i].cell_coverage) || + !eq(raster->cells[i].opposite_coverage, refraster->cells[i].opposite_coverage)) { + print_raster(refraster); + print_raster(raster); + } + ASSERT(eq(raster->cells[i].cell_coverage, refraster->cells[i].cell_coverage)); + ASSERT(eq(raster->cells[i].opposite_coverage, refraster->cells[i].opposite_coverage)); + } + } + rtgrpblib_reset_raster(raster, 10, 10); + rtgrpblib_reset_raster(refraster, 10, 10); +} + + +static void +check_simple_lines(void) +{ + check_line(1, 1, 2, 2, 3, 3, 1); + check_line(1, 1, 3, 3, 2, 2, 1); + check_line(2, 2, 1, 1, 3, 3, 1); + check_line(2, 2, 3, 3, 1, 1, 1); + check_line(3, 3, 1, 1, 2, 2, 1); + check_line(3, 3, 2, 2, 1, 1, 1); + check_line(1, 1, 3, 3, 3, 3, 1); + check_line(1, 1, 1, 1, 3, 3, 1); + + check_line(1, 4, 2, 4, 3, 4, 1); + check_line(1, 4, 3, 4, 2, 4, 1); + check_line(2, 4, 1, 4, 3, 4, 1); + check_line(2, 4, 3, 4, 1, 4, 1); + check_line(3, 4, 1, 4, 2, 4, 1); + check_line(3, 4, 2, 4, 1, 4, 1); + check_line(1, 4, 3, 4, 3, 4, 1); + check_line(1, 4, 1, 4, 3, 4, 1); + + check_line(4, 1, 4, 2, 4, 3, 1); + check_line(4, 1, 4, 3, 4, 2, 1); + check_line(4, 2, 4, 1, 4, 3, 1); + check_line(4, 2, 4, 3, 4, 1, 1); + check_line(4, 3, 4, 1, 4, 2, 1); + check_line(4, 3, 4, 2, 4, 1, 1); + check_line(4, 1, 4, 3, 4, 3, 1); + check_line(4, 1, 4, 1, 4, 3, 1); +} + + +static void +check_random_bounded_lines(int exact) +{ + double x1, x2, x3; + double y1, y2, y3; + double mid; + size_t i; + + for (i = 0; i < 100000UL; i++) { + x1 = floor(frand(0, 11)); + y1 = floor(frand(0, 11)); + x3 = floor(frand(0, 11)); + y3 = floor(frand(0, 11)); + x1 -= (double)(x1 > 10); + x2 -= (double)(x2 > 10); + y1 -= (double)(y1 > 10); + y2 -= (double)(y2 > 10); + mid = frand(0, 1); + + if (x3 - x1) { + x2 = floor(mid * (x3 - x1) + x1); + y2 = y1 + (x2 - x1) * (y3 - y1) / (x3 - x1); + } else if (y3 - y1) { + x2 = x1; + y2 = floor(mid * (y3 - y1) + y1); + } else { + x2 = x1; + y2 = y1; + } + + if (!exact) + check_line(x1, y1, x2, y2, x3, y3, x2 == floor(x2) && y2 == floor(y2)); + else if (x2 == floor(x2) && y2 == floor(y2)) + check_line(x1, y1, x2, y2, x3, y3, 1); + } +} + + +static void +check_random_unbounded_lines(int exact) +{ + double x1, x2, x3; + double y1, y2, y3; + double mid; + size_t i; + + for (i = 0; i < 100000UL; i++) { + x1 = floor(frand(-5, 15)); + y1 = floor(frand(-5, 15)); + x3 = floor(frand(-5, 15)); + y3 = floor(frand(-5, 15)); + mid = frand(-2, 2); + + if (x3 - x1) { + x2 = floor(mid * (x3 - x1) + x1); + y2 = y1 + (x2 - x1) * (y3 - y1) / (x3 - x1); + } else if (y3 - y1) { + x2 = x1; + y2 = floor(mid * (y3 - y1) + y1); + } else { + x2 = x1; + y2 = y1; + } + + if (!exact) + check_line(x1, y1, x2, y2, x3, y3, x2 == floor(x2) && y2 == floor(y2)); + else if (x2 == floor(x2) && y2 == floor(y2)) + check_line(x1, y1, x2, y2, x3, y3, 1); + } +} + + int main(void) { - return 0; /* TODO add test */ + raster = rtgrpblib_create_raster(10, 10); + ASSERT(raster); + refraster = rtgrpblib_create_raster(10, 10); + ASSERT(refraster); + srand((unsigned)(uintptr_t)raster); + + check_simple_lines(); + check_random_bounded_lines(1); + check_random_unbounded_lines(1); + //TODO check_random_bounded_lines(0); + //TODO check_random_unbounded_lines(0); + raster->draftness = -1; + refraster->draftness = -1; + check_simple_lines(); + check_random_bounded_lines(1); + check_random_unbounded_lines(1); +#ifdef TODO_NOT_IMPLEMENTED + check_random_bounded_lines(0); + check_random_unbounded_lines(0); +#endif + raster->draftness = 0.5; + refraster->draftness = 0.5; + + /* TODO add tests */ + + free(raster); + free(refraster); + return 0; } |