Rev 11124 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 11124 | Rev 12248 | ||
---|---|---|---|
Line 56... | Line 56... | ||
56 | int xfn=0, yfn=0; |
56 | int xfn=0, yfn=0; |
57 | int discrete; |
57 | int discrete; |
58 | double dist1, dist2, max1, max2, ratio1, ratio2, rep1, rep2; |
58 | double dist1, dist2, max1, max2, ratio1, ratio2, rep1, rep2; |
59 | double djump1, djump2; |
59 | double djump1, djump2; |
60 | struct cv { |
60 | struct cv { |
61 |
|
61 | int x,y, closest, rep; |
62 |
|
62 | double dist; |
63 | } cv1[pointlim], cv2[pointlim]; |
63 | } cv1[pointlim], cv2[pointlim]; |
64 | int points1,points2; |
64 | int points1,points2; |
65 | 65 | ||
66 | int Abs(int t) {if(t>=0) return t; else return -t;} |
66 | int Abs(int t) {if(t>=0) return t; else return -t;} |
67 | int Min(int x,int y) {if(x>y) return y; else return x;} |
67 | int Min(int x,int y) {if(x>y) return y; else return x;} |
Line 69... | Line 69... | ||
69 | 69 | ||
70 | int listbuf[pointlim*2], listcnt; |
70 | int listbuf[pointlim*2], listcnt; |
71 | 71 | ||
72 | void reverse(struct cv *cvbuf, int cnt) |
72 | void reverse(struct cv *cvbuf, int cnt) |
73 | { |
73 | { |
74 |
|
74 | int i; |
75 |
|
75 | struct cv cvt; |
76 |
|
76 | for(i=0;i<cnt/2;i++) { |
77 |
|
77 | memmove(&cvt,cvbuf+i,sizeof(cvt)); |
78 |
|
78 | memmove(cvbuf+i,cvbuf+(cnt-i-1),sizeof(cvt)); |
79 |
|
79 | memmove(cvbuf+(cnt-i-1),&cvt,sizeof(cvt)); |
80 |
|
80 | } |
81 | } |
81 | } |
82 | 82 | ||
83 | int str2list(char *p, int lim) |
83 | int str2list(char *p, int lim) |
84 | { |
84 | { |
85 |
|
85 | char *p2; |
86 |
|
86 | for(p2=strchr(p,';'); p2; p2=strchr(p2+1,';')) *p2=','; |
87 |
|
87 | for(listcnt=0; p && listcnt<lim; p=p2) { |
88 |
|
88 | p2=strchr(p,','); if(p2!=NULL) *p2++=0; |
89 |
|
89 | p=find_word_start(p); if(*p==0) continue; |
90 |
|
90 | listbuf[listcnt++]=atoi(p); |
91 |
|
91 | } |
92 |
|
92 | return listcnt; |
93 | } |
93 | } |
- | 94 | ||
- | 95 | int list2curve(struct cv *cvbuf) |
|
- | 96 | { |
|
- | 97 | int i, j, m, t, st, xx, yy, x2, y2, x3, y3, ll; |
|
94 | 98 | ||
95 | int list2curve(struct cv *cvbuf) |
- | |
96 | { |
- | |
97 | int i, j, m, t, st, xx, yy, x2, y2, x3, y3, ll; |
- | |
98 | - | ||
99 |
|
99 | ll=listcnt/2; if(ll<2) return 0; |
100 |
|
100 | xx=listbuf[0]; yy=listbuf[1]; |
101 |
|
101 | j=0; if(xx>=bx[0] && xx<=bx[1] && yy>=by[0] && yy<=by[1]) { |
102 |
|
102 | cvbuf[0].x=xx; cvbuf[0].y=yy; j++; |
103 |
|
103 | } |
104 |
|
104 | for(i=1; i<ll && j<pointlim; i++) { |
105 |
|
105 | x2=listbuf[2*i]; y2=listbuf[2*i+1]; |
106 |
|
106 | m=Max(Abs(x2-xx),Abs(y2-yy)); if(m<=0) continue; |
107 |
|
107 | if(discrete==1) st=m; else st=1; |
108 |
|
108 | for(t=st; t<=m && j<pointlim; t++) { |
109 |
|
109 | x3=(double) (x2*t+xx*(m-t))/m+0.5; |
110 |
|
110 | y3=(double) (y2*t+yy*(m-t))/m+0.5; |
111 |
|
111 | if(x3>=bx[0] && x3<=bx[1] && y3>=by[0] && y3<=by[1]) { |
112 |
|
112 | cvbuf[j].x=x3; cvbuf[j].y=y3; cvbuf[j].dist=-1; |
113 |
|
113 | cvbuf[j].rep=0; j++; |
114 | } |
- | |
115 | } |
114 | } |
116 | xx=x2; yy=y2; |
- | |
117 | } |
115 | } |
- | 116 | xx=x2; yy=y2; |
|
- | 117 | } |
|
118 |
|
118 | return j; |
119 | } |
119 | } |
120 | 120 | ||
121 | void compare(void) |
121 | void compare(void) |
122 | { |
122 | { |
123 |
|
123 | int i, j, cl; |
124 |
|
124 | double d, dt; |
125 | 125 | ||
126 |
|
126 | d=2*pointlim; cl=-1; |
127 |
|
127 | for(i=0,djump1=1;i<points1-1;i++) { |
128 |
|
128 | dt=sqrt(pow(cv1[i].x-cv1[i+1].x,2)+pow(cv1[i].y-cv1[i+1].y,2)); |
129 |
|
129 | if(dt>djump1) djump1=dt; |
130 |
|
130 | } |
131 |
|
131 | for(i=0,djump2=1;i<points2-1;i++) { |
132 |
|
132 | dt=sqrt(pow(cv2[i].x-cv2[i+1].x,2)+pow(cv2[i].y-cv2[i+1].y,2)); |
133 |
|
133 | if(dt>djump2) djump2=dt; |
134 |
|
134 | } |
135 |
|
135 | for(i=0;i<points1;i++) { |
136 |
|
136 | for(j=0;j<points2;j++) { |
137 |
|
137 | dt=sqrt(pow(cv2[j].x-cv1[i].x,2)+pow(cv2[j].y-cv1[i].y,2)); |
138 |
|
138 | if(dt<d) {d=dt; cl=j;} |
139 |
|
139 | else {dt=(dt-d)/djump2; if(dt>2) j+=dt-1;} |
140 |
|
140 | } |
141 |
|
141 | cv1[i].dist=d; cv1[i].closest=cl; |
142 |
|
142 | if(i<points1) |
143 |
|
143 | d+=sqrt(pow(cv1[i].x-cv1[i+1].x,2)+pow(cv1[i].y-cv1[i+1].y,2))+0.1; |
144 |
|
144 | } |
- | 145 | d=2*pointlim; |
|
145 |
|
146 | for(i=0;i<points2;i++) { |
146 |
|
147 | for(j=0;j<points1;j++) { |
147 |
|
148 | dt=sqrt(pow(cv1[j].x-cv2[i].x,2)+pow(cv1[j].y-cv2[i].y,2)); |
148 |
|
149 | if(dt<d) {d=dt; cl=j;} |
149 |
|
150 | else {dt=(dt-d)/djump1; if(dt>2) j+=dt-1;} |
150 |
|
151 | } |
151 |
|
152 | cv2[i].dist=d; cv2[i].closest=cl; |
152 |
|
153 | if(i<points2) |
153 |
|
154 | d+=sqrt(pow(cv2[i].x-cv2[i+1].x,2)+pow(cv2[i].y-cv2[i+1].y,2))+0.1; |
154 |
|
155 | } |
155 |
|
156 | for(i=1, cl=cv1[0].closest;i<points1;i++) { |
156 |
|
157 | j=cv1[i].closest; if(j!=cl) cv2[j].rep++; |
157 |
|
158 | cl=j; |
158 |
|
159 | } |
159 |
|
160 | for(i=1, cl=cv2[0].closest;i<points2;i++) { |
160 |
|
161 | j=cv2[i].closest; if(j!=cl) cv1[j].rep++; |
161 |
|
162 | cl=j; |
162 |
|
163 | } |
163 |
|
164 | for(i=cl=0; i<points1; i++) if(cv1[i].rep>1) cl+=cv1[i].rep-1; |
164 |
|
165 | rep1=(double) cl/points1; |
165 |
|
166 | for(i=cl=0; i<points1; i++) if(cv2[i].rep>1) cl+=cv2[i].rep-1; |
166 |
|
167 | rep2=(double) cl/points2; |
- | 168 | } |
|
- | 169 | ||
- | 170 | void check(void) |
|
- | 171 | { |
|
- | 172 | int i,j,xret1,yret1,xret2,yret2; |
|
- | 173 | int xx,yy,xmin,xmax,ymin,ymax; |
|
- | 174 | double d; |
|
- | 175 | max1=max2=0; |
|
- | 176 | for(i=j=0,d=0;i<points1;i++) { |
|
- | 177 | if(cv1[i].dist<=tol) j++; |
|
- | 178 | d+=pow(cv1[i].dist,4); |
|
- | 179 | if(max1<cv1[i].dist) max1=cv1[i].dist; |
|
- | 180 | } |
|
- | 181 | ratio1=(double) j/points1; dist1=pow(d/points1,0.25)*1.8; |
|
- | 182 | for(i=j=0,d=0;i<points2;i++) { |
|
- | 183 | if(cv2[i].dist<=tol) j++; |
|
- | 184 | d+=pow(cv2[i].dist,4); |
|
- | 185 | if(max2<cv2[i].dist) max2=cv2[i].dist; |
|
- | 186 | } |
|
- | 187 | ratio2=(double) j/points2; dist2=pow(d/points2,0.25)*1.8; |
|
- | 188 | xret1=xret2=yret1=yret2=0; |
|
- | 189 | xmin=xmax=cv2[0].x; ymin=ymax=cv2[0].y; |
|
- | 190 | for(i=1;i<points2;i++) { |
|
- | 191 | xx=cv2[i].x; yy=cv2[i].y; |
|
- | 192 | xret1=Max(xret1,xmax-xx); xret2=Max(xret2,xx-xmin); |
|
- | 193 | yret1=Max(yret1,ymax-yy); yret2=Max(yret2,yy-ymin); |
|
- | 194 | xmin=Min(xx,xmin);xmax=Max(xx,xmax); |
|
- | 195 | ymin=Min(yy,ymin);ymax=Max(yy,ymax); |
|
- | 196 | } |
|
- | 197 | if(Min(xret1,xret2)<=2) xfn=1; |
|
- | 198 | if(Min(yret1,yret2)<=2) yfn=1; |
|
167 | } |
199 | } |
168 | 200 | ||
169 | void |
201 | void output(void) |
170 | { |
202 | { |
171 | int i,j,xret1,yret1,xret2,yret2; |
- | |
172 | int xx,yy,xmin,xmax,ymin,ymax; |
- | |
173 | double d; |
- | |
174 | max1=max2=0; |
- | |
175 | for(i=j=0,d=0;i<points1;i++) { |
- | |
176 | if(cv1[i].dist<=tol) j++; |
- | |
177 | d+=pow(cv1[i].dist,4); |
- | |
178 | if(max1<cv1[i].dist) max1=cv1[i].dist; |
- | |
179 | } |
- | |
180 | ratio1=(double) j/points1; dist1=pow(d/points1,0.25)*1.8; |
- | |
181 | for(i=j=0,d=0;i<points2;i++) { |
- | |
182 | if(cv2[i].dist<=tol) j++; |
- | |
183 | d+=pow(cv2[i].dist,4); |
- | |
184 | if(max2<cv2[i].dist) max2=cv2[i].dist; |
- | |
185 | } |
- | |
186 | ratio2=(double) j/points2; dist2=pow(d/points2,0.25)*1.8; |
- | |
187 | xret1=xret2=yret1=yret2=0; |
- | |
188 | xmin=xmax=cv2[0].x; ymin=ymax=cv2[0].y; |
- | |
189 | for(i=1;i<points2;i++) { |
- | |
190 | xx=cv2[i].x; yy=cv2[i].y; |
- | |
191 | xret1=Max(xret1,xmax-xx); xret2=Max(xret2,xx-xmin); |
- | |
192 | yret1=Max(yret1,ymax-yy); yret2=Max(yret2,yy-ymin); |
- | |
193 | xmin=Min(xx,xmin);xmax=Max(xx,xmax); |
- | |
194 | ymin=Min(yy,ymin);ymax=Max(yy,ymax); |
- | |
195 | } |
- | |
196 | if(Min(xret1,xret2)<=2) xfn=1; |
- | |
197 | if(Min(yret1,yret2)<=2) yfn=1; |
- | |
198 | } |
- | |
199 | - | ||
200 | void output(void) |
- | |
201 | { |
- | |
202 |
|
203 | printf("%.2f %.2f %.2f %.2f \ |
203 | %.3f %.3f %.1f %.1f \ |
204 | %.3f %.3f %.1f %.1f \ |
204 | %.3f %.3f", |
205 | %.3f %.3f", |
205 | dist1, dist2, max1, max2, |
206 | dist1, dist2, max1, max2, |
206 | ratio1, ratio2, djump1, djump2, |
207 | ratio1, ratio2, djump1, djump2, |
207 | rep1, rep2); |
208 | rep1, rep2); |
208 |
|
209 | if(xfn) printf(" fx"); |
209 |
|
210 | if(yfn) printf(" fy"); |
210 | } |
211 | } |
211 | 212 | ||
212 | void test(void) |
213 | void test(void) |
213 | { |
214 | { |
214 |
|
215 | int i; |
215 |
|
216 | for(i=0;i<points1;i++) printf("%d,%d,%d,%.2f\n", |
216 |
|
217 | cv1[i].x,cv1[i].y,cv1[i].closest,cv1[i].dist); |
217 |
|
218 | printf("\n"); |
218 |
|
219 | for(i=0;i<points2;i++) printf("%d,%d,%d,%.2f\n", |
219 |
|
220 | cv2[i].x,cv2[i].y,cv2[i].closest,cv2[i].dist); |
220 |
|
221 | printf("\n"); |
221 | } |
222 | } |
222 | 223 | ||
223 | int main(int argc, char *argv[]) |
224 | int main(int argc, char *argv[]) |
224 | { |
225 | { |
225 |
|
226 | int i; |
226 |
|
227 | char *c1, *c2, *op; |
227 |
|
228 | c1=getenv("w_curvecomp_1"); c2=getenv("w_curvecomp_2"); |
228 | /* nothing to do */ |
229 | /* nothing to do */ |
229 |
|
230 | if(c1==NULL || c2==NULL || *c1==0 || *c2==0) return 0; |
230 |
|
231 | snprintf(curve1,sizeof(curve1),"%s",c1); |
231 |
|
232 | snprintf(curve2,sizeof(curve2),"%s",c2); |
232 |
|
233 | bx[0]=by[0]=bx[1]=by[1]=-1; |
233 |
|
234 | c1=getenv("w_curvecomp_xrange"); c2=getenv("w_curvecomp_yrange"); |
234 |
|
235 | if(c1!=NULL && *c1!=0) { |
235 |
|
236 | str2list(c1,2); for(i=0;i<listcnt;i++) bx[i]=listbuf[i]; |
236 |
|
237 | } |
237 |
|
238 | if(c2!=NULL && *c2!=0) { |
238 |
|
239 | str2list(c2,2); for(i=0;i<listcnt;i++) by[i]=listbuf[i]; |
239 |
|
240 | } |
240 |
|
241 | op=getenv("w_curvecomp_option"); if(op==NULL) op=""; |
241 |
|
242 | if(bx[0]==-1) bx[0]=0; |
242 |
|
243 | if(bx[1]==-1) bx[1]=pointlim; |
243 |
|
244 | if(by[0]==-1) by[0]=0; |
244 |
|
245 | if(by[1]==-1) by[1]=pointlim; |
245 |
|
246 | c1=getenv("w_curvecomp_tolerance"); |
246 |
|
247 | if(c1!=NULL && *c1!=0) tol=atoi(c1); |
247 |
|
248 | tol=Min(30,Max(5,tol)); |
248 | 249 | ||
249 |
|
250 | if(strstr(op,"discrete1")!=NULL) discrete=1; else discrete=0; |
250 |
|
251 | str2list(curve1,pointlim*2); points1=list2curve(cv1); |
251 |
|
252 | if(strstr(op,"discrete2")!=NULL) discrete=1; else discrete=0; |
252 |
|
253 | str2list(curve2,pointlim*2); points2=list2curve(cv2); |
253 |
|
254 | if(points1<2 || points2<2) return 0; |
254 |
|
255 | compare(); check(); output(); |
255 |
|
256 | return 0; |
256 | } |
257 | } |