Rev 11126 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 11126 | Rev 12260 | ||
---|---|---|---|
Line 16... | Line 16... | ||
16 | */ |
16 | */ |
17 | #include "libwims.h" |
17 | #include "libwims.h" |
18 | 18 | ||
19 | static int _lcomp(const void *l1, const void *l2) |
19 | static int _lcomp(const void *l1, const void *l2) |
20 | { |
20 | { |
21 |
|
21 | const double *d1, *d2; |
22 |
|
22 | double d; |
23 |
|
23 | d1=(const double *) l1; d2=(const double *) l2; |
24 |
|
24 | d=*d1-*d2; |
25 |
|
25 | if(d<0) return -1; |
26 |
|
26 | if(d>0) return 1; |
27 |
|
27 | return 0; |
28 | } |
28 | } |
29 | 29 | ||
30 | static double lc_scalex(leveldata *ld, int x) |
30 | static double lc_scalex(leveldata *ld, int x) |
31 | { |
31 | { |
32 |
|
32 | if(x<0) x=0; |
33 |
|
33 | if(x>=ld->xsize) x=ld->xsize-1; |
34 |
|
34 | return ld->xspan*((double) x - 0.40127)/ld->xsize+ld->xrange[0]; |
35 | } |
35 | } |
36 | 36 | ||
37 | static double lc_scaley(leveldata *ld, int y) |
37 | static double lc_scaley(leveldata *ld, int y) |
38 | { |
38 | { |
39 |
|
39 | if(y<0) y=0; |
40 |
|
40 | if(y>=ld->ysize) y=ld->ysize-1; |
41 |
|
41 | return -ld->yspan*((double) y - 0.40127)/ld->ysize+ld->yrange[1]; |
42 | } |
42 | } |
43 | 43 | ||
44 | static int _getlevel(leveldata *ld, int x, int y) |
44 | static int _getlevel(leveldata *ld, int x, int y) |
45 | { |
45 | { |
46 |
|
46 | double dd; |
47 |
|
47 | int i; |
48 | 48 | ||
49 |
|
49 | eval_setval(ld->xevpos,lc_scalex(ld,x)); |
50 |
|
50 | eval_setval(ld->yevpos,lc_scaley(ld,y)); |
51 |
|
51 | dd=checked_eval(ld->fn); |
52 |
|
52 | for(i=0;i<ld->levelcnt && dd>ld->levels[i];i++); |
53 |
|
53 | return i; |
54 | } |
54 | } |
55 | 55 | ||
56 | static void lc_replacexy(leveldata *ld) |
56 | static void lc_replacexy(leveldata *ld) |
57 | { |
57 | { |
58 |
|
58 | char *pp; |
59 |
|
59 | for(pp=varchr(ld->fn,ld->xname);pp!=NULL;pp=varchr(pp,ld->xname)) { |
60 |
|
60 | string_modify(ld->fn,pp,pp+strlen(ld->xname),EV_X); |
61 |
|
61 | pp+=strlen(EV_X); |
62 |
|
62 | } |
63 |
|
63 | for(pp=varchr(ld->fn,ld->yname);pp!=NULL;pp=varchr(pp,ld->yname)) { |
64 |
|
64 | string_modify(ld->fn,pp,pp+strlen(ld->yname),EV_Y); |
65 |
|
65 | pp+=strlen(EV_Y); |
66 |
|
66 | } |
67 | } |
67 | } |
68 | 68 | ||
69 | /* produces level curve data. Returns non-zero if error. */ |
69 | /* produces level curve data. Returns non-zero if error. */ |
70 | int levelcurve(leveldata *ld) |
70 | int levelcurve(leveldata *ld) |
71 | { |
71 | { |
72 |
|
72 | int xx,yy,xi,yi,xsteps,ysteps; |
73 |
|
73 | int i,x,y,xt,yt; |
74 |
|
74 | short int l1[LEVELSIZE_LIM+16], l2[LEVELSIZE_LIM+16]; |
75 |
|
75 | short int l3[LEVELGRAIN_LIM+2][LEVELGRAIN_LIM+2]; |
76 |
|
76 | char f[MAX_LINELEN+1]; |
77 | 77 | ||
78 |
|
78 | ld->datacnt=0; |
79 |
|
79 | if(ld->fn==NULL || *(ld->fn)==0 || ld->levelcnt<1) return 1; |
80 |
|
80 | if(ld->grain<1) ld->grain=4; |
81 |
|
81 | if(ld->grain>LEVELGRAIN_LIM) ld->grain=LEVELGRAIN_LIM; |
82 |
|
82 | if(ld->levelcnt>LEVEL_LIM) ld->levelcnt=LEVEL_LIM; |
83 |
|
83 | if(ld->xsize<10 || ld->xsize>LEVELSIZE_LIM) return 2; |
84 |
|
84 | if(ld->ysize<10 || ld->ysize>LEVELSIZE_LIM) return 2; |
85 |
|
85 | if(check_parentheses(ld->fn,0)) return 3; |
86 |
|
86 | ld->xspan=ld->xrange[1]-ld->xrange[0]; |
87 |
|
87 | ld->yspan=ld->yrange[1]-ld->yrange[0]; |
88 |
|
88 | if(ld->levelcnt>1) qsort(ld->levels,ld->levelcnt,sizeof(double),_lcomp); |
89 |
|
89 | if(ld->xname==NULL || *(ld->xname)==0) ld->xname="x"; |
90 |
|
90 | if(ld->yname==NULL || *(ld->yname)==0) ld->yname="y"; |
91 |
|
91 | snprintf(f,sizeof(f),"%s",ld->fn); substitute(f); ld->fn=f; |
92 |
|
92 | ld->xevpos=eval_getpos(EV_X); ld->yevpos=eval_getpos(EV_Y); |
93 |
|
93 | if(ld->xevpos<0 || ld->yevpos<0) return 4; |
94 |
|
94 | lc_replacexy(ld); evalue_compile(f); |
95 |
|
95 | xsteps=(ld->xsize+ld->grain-1)/ld->grain+1; |
96 |
|
96 | ysteps=(ld->ysize+ld->grain-1)/ld->grain+1; |
97 |
|
97 | for(yy=yi=0;yi<ysteps;yy+=ld->grain,yi++) l2[yi]=_getlevel(ld,0,yy); |
- | 98 | l2[ysteps]=l2[ysteps-1]; |
|
- | 99 | for(xi=1,xx=ld->grain;xi<xsteps && ld->datacnt<LEVELPOINT_LIM;xx+=ld->grain,xi++) { |
|
- | 100 | memmove(l1,l2,(ysteps+1)*sizeof(short int)); |
|
- | 101 | for(yi=yy=0;yi<ysteps;yy+=ld->grain,yi++) l2[yi]=_getlevel(ld,xx,yy); |
|
98 | l2[ysteps]=l2[ysteps-1]; |
102 | l2[ysteps]=l2[ysteps-1]; |
99 | for(xi=1,xx=ld->grain;xi<xsteps && ld->datacnt<LEVELPOINT_LIM;xx+=ld->grain,xi++) { |
- | |
100 | memmove(l1,l2,(ysteps+1)*sizeof(short int)); |
- | |
101 | for(yi=yy=0;yi<ysteps;yy+=ld->grain,yi++) l2[yi]=_getlevel(ld,xx,yy); |
- | |
102 | l2[ysteps]=l2[ysteps-1]; |
- | |
103 |
|
103 | for(yi=0;yi<ysteps && ld->datacnt<LEVELPOINT_LIM;yi++) |
104 |
|
104 | if(l1[yi]!=l1[yi+1] || l1[yi]!=l2[yi] || l1[yi]!=l2[yi+1]) { |
105 |
|
105 | for(x=0,xt=(xi-1)*ld->grain;x<=ld->grain;x++,xt++) |
106 |
|
106 | for(y=0,yt=yi*ld->grain;y<=ld->grain;y++,yt++) { |
107 |
|
107 | if(x==0 && y==0) {l3[x][y]=l1[yi]; continue;} |
108 |
|
108 | if(x==0 && y==ld->grain) {l3[x][y]=l1[yi+1]; continue;} |
109 |
|
109 | if(x==ld->grain && y==0) {l3[x][y]=l2[yi]; continue;} |
110 |
|
110 | if(x==ld->grain && y==ld->grain) {l3[x][y]=l2[yi+1]; continue;} |
111 |
|
111 | l3[x][y]=_getlevel(ld,xt,yt); |
112 |
|
112 | } |
113 |
|
113 | for(x=0,xt=(xi-1)*ld->grain;x<ld->grain;x++,xt++) |
114 |
|
114 | for(y=0,yt=yi*ld->grain;y<ld->grain;y++,yt++) { |
115 |
|
115 | i=l3[x][y]; |
116 |
|
116 | if((i!=l3[x][y+1] || i!=l3[x+1][y]) && |
117 |
|
117 | ld->datacnt<LEVELPOINT_LIM && |
118 |
|
118 | (i!=l3[x][y+1] || ld->datacnt==0 || |
119 |
|
119 | l3[x+1][y+1]==l3[x+1][y] || |
120 |
|
120 | ld->xdata[ld->datacnt-1]!=xt || |
121 |
|
121 | ld->ydata[ld->datacnt-1]!=yt-1)) { |
122 |
|
122 | ld->xdata[ld->datacnt]=xt; |
123 |
|
123 | ld->ydata[ld->datacnt++]=yt; |
124 |
|
124 | } |
125 |
|
125 | } |
126 |
|
126 | } |
127 |
|
127 | } |
128 |
|
128 | return 0; |
129 | } |
129 | } |
130 | - |