Index: erode.c =================================================================== --- erode.c (revision 7413) +++ erode.c (revision 7414) @@ -9,7 +9,6 @@ #include "pcb_draw.h" - int stat[100]; static inline void ray(image_t *i, double x, double y, double dx, double dy, int *out) @@ -44,6 +43,60 @@ return h; } +static int near(int *hg, int my, double cx, double cy, int width, int clear) +{ + int x1 = round(cx - 1), x2 = round(cx + 1); + int y1 = round(cy - 1), y2 = round(cy + 1); + int x, y; + for(y = y1; y <= y2; y++) { + for(x = x1; x <= x2; x++) { + if (hg[x + y*width] == my) { + if (clear) + hg[x + y*width] = 0; + return 1; + } + } + } + return 0; +} + +static int find_line(image_t *trace, int *hg, int my, int cx, int cy, double ang, int width) +{ + double dx, dy, x, y, ex, ey; + int len = -2; + + dx = cos(ang); + dy = sin(ang); + x = cx; + y = cy; + do { + len++; + x += dx; + y += dy; + if (trace != NULL) { + image_pix(trace, (int)round(x), (int)round(y)) = pixel_blue; + hg[(int)round(x) + (int)round(y) * width] = 0; + } + } while(near(hg, my, x, y, width, trace != NULL)); + ex = x; + ey = y; + x = cx; + y = cy; + do { + len++; + x -= dx; + y -= dy; + if (trace != NULL) { + image_pix(trace, (int)round(x), (int)round(y)) = pixel_blue; + hg[(int)round(x) + (int)round(y) * width] = 0; + } + } while(near(hg, my, x, y, width, trace != NULL)); + if (trace != NULL) { + printf("stroke %d %d %d %d\n", (int)round(ex), (int)round(ey), (int)round(x), (int)round(y)); + } + return len; +} + int main(int arc, char *argv[]) { image_t *ref; @@ -50,7 +103,7 @@ int *hg; int maxh = 0; int x, y, n, cutoff, end; - char *ref_fn = "1.pnm"; + char *ref_fn = "l.pnm"; if (argv[1] != NULL) ref_fn = argv[1]; @@ -57,6 +110,7 @@ ref = pnm_load(ref_fn); + /* height map */ hg = calloc(sizeof(int), ref->sx * ref->sy); for(y = 1; y < ref->sy-1; y++) { for(x = 1; x < ref->sy-1; x++) { @@ -81,8 +135,9 @@ printf("-- cutoff=%d\n", cutoff); end = ref->sx * ref->sy; for(n = 0; n < end; n++) { - if (hg[n] == cutoff) + if (hg[n] == cutoff) { ref->pixmap[n] = pixel_red; + } else if (ref->pixmap[n].r != 255) { ref->pixmap[n].r = 200; ref->pixmap[n].g = 200; @@ -89,6 +144,35 @@ ref->pixmap[n].b = 200; } } + + + /* brute force lines */ + for(;;) { + int best_len = 0, bestx, besty; + double besta; + for(n = 0; n < end; n++) { + if (hg[n] == cutoff) { + double a; + int x, y; + x = image_x(ref, ref->pixmap+n); + y = image_y(ref, ref->pixmap+n); + for(a = 0; a < M_PI; a+=0.1) { + int len = find_line(NULL, hg, cutoff, x, y, a, ref->sx); + if (len > best_len) { + best_len = len; + bestx = x; + besty = y; + besta = a; + } + } + } + } + if (best_len <= cutoff*3) + break; + printf("len=%d\n", best_len); + find_line(ref, hg, cutoff, bestx, besty, besta, ref->sx); + } + pnm_save(ref, "OUT.pnm"); }