[lib_netmap] -Fix: map_j2nets: call two-net postproc at the end of mapping a 2net...
[pcb-rnd-mirror.git] / work / gpstroke / erode.c
blobb3eb57ce739fa1e38b1b869a7b3b407c298265e5
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <math.h>
4 #include <string.h>
5 #include <time.h>
6 #include "c24lib/image/image.h"
7 #include "c24lib/image/draw.h"
8 #include "c24lib/image/pnm.h"
10 #include "pcb_draw.h"
12 int stat[100];
14 static inline void ray(image_t *i, double x, double y, double dx, double dy, int *out)
16 pixel_t *p;
17 int h = 0, xx, yy;
18 do {
19 x += dx;
20 y += dy;
21 xx = round(x);
22 yy = round(y);
23 p = &image_pix(i, xx, yy);
24 h++;
26 } while(p->r == 0);
28 if (h < *out)
29 *out = h;
32 static inline int height(image_t *i, int cx, int cy)
34 pixel_t *p;
35 double dx, dy;
36 int h = i->sx + i->sy;
37 p = &image_pix(i, cx, cy);
38 if (p->r != 0)
39 return 0;
40 for(dy = -1.0; dy <= 1.0; dy+=0.27)
41 for(dx = -1.0; dx <= 1.0; dx+=0.27)
42 ray(i, (double)cx, (double)cy, dx, dy, &h);
43 return h;
46 static int near(int *hg, int my, double cx, double cy, int width, int clear)
48 int x1 = round(cx - 1), x2 = round(cx + 1);
49 int y1 = round(cy - 1), y2 = round(cy + 1);
50 int x, y;
51 for(y = y1; y <= y2; y++) {
52 for(x = x1; x <= x2; x++) {
53 if (hg[x + y*width] == my) {
54 if (clear)
55 hg[x + y*width] = 0;
56 return 1;
60 return 0;
63 static int find_line(image_t *trace, int *hg, int my, int cx, int cy, double ang, int width)
65 double dx, dy, x, y, ex, ey;
66 int len = -2;
68 dx = cos(ang);
69 dy = sin(ang);
70 x = cx;
71 y = cy;
72 do {
73 len++;
74 x += dx;
75 y += dy;
76 if (trace != NULL) {
77 image_pix(trace, (int)round(x), (int)round(y)) = pixel_blue;
78 hg[(int)round(x) + (int)round(y) * width] = 0;
80 } while(near(hg, my, x, y, width, trace != NULL));
81 ex = x;
82 ey = y;
83 x = cx;
84 y = cy;
85 do {
86 len++;
87 x -= dx;
88 y -= dy;
89 if (trace != NULL) {
90 image_pix(trace, (int)round(x), (int)round(y)) = pixel_blue;
91 hg[(int)round(x) + (int)round(y) * width] = 0;
93 } while(near(hg, my, x, y, width, trace != NULL));
94 if (trace != NULL) {
95 printf("stroke %d %d %d %d\n", (int)round(ex), (int)round(ey), (int)round(x), (int)round(y));
97 return len;
100 int main(int arc, char *argv[])
102 image_t *ref;
103 int *hg;
104 int maxh = 0;
105 int x, y, n, cutoff, end;
106 char *ref_fn = "l.pnm";
108 if (argv[1] != NULL)
109 ref_fn = argv[1];
111 ref = pnm_load(ref_fn);
113 /* height map */
114 hg = calloc(sizeof(int), ref->sx * ref->sy);
115 for(y = 1; y < ref->sy-1; y++) {
116 for(x = 1; x < ref->sy-1; x++) {
117 int h = height(ref, x, y);
118 if (h > maxh)
119 maxh = h;
120 stat[h]++;
121 printf("%d", h);
122 hg[x + y*ref->sx] = h;
124 printf("\n");
127 cutoff = 0;
128 for(n = 1; n <= maxh; n++) {
129 printf("h=%d %d\n", n, stat[n]);
130 if ((n > 1) && (stat[n] < stat[n-1]/2) && (cutoff == 0)) {
131 cutoff = n-1;
135 printf("-- cutoff=%d\n", cutoff);
136 end = ref->sx * ref->sy;
137 for(n = 0; n < end; n++) {
138 if (hg[n] == cutoff) {
139 ref->pixmap[n] = pixel_red;
141 else if (ref->pixmap[n].r != 255) {
142 ref->pixmap[n].r = 200;
143 ref->pixmap[n].g = 200;
144 ref->pixmap[n].b = 200;
149 /* brute force lines */
150 for(;;) {
151 int best_len = 0, bestx, besty;
152 double besta;
153 for(n = 0; n < end; n++) {
154 if (hg[n] == cutoff) {
155 double a;
156 int x, y;
157 x = image_x(ref, ref->pixmap+n);
158 y = image_y(ref, ref->pixmap+n);
159 for(a = 0; a < M_PI; a+=0.1) {
160 int len = find_line(NULL, hg, cutoff, x, y, a, ref->sx);
161 if (len > best_len) {
162 best_len = len;
163 bestx = x;
164 besty = y;
165 besta = a;
170 if (best_len <= cutoff*3)
171 break;
172 printf("len=%d\n", best_len);
173 find_line(ref, hg, cutoff, bestx, besty, besta, ref->sx);
176 pnm_save(ref, "OUT.pnm");