Rev 7847 | Rev 11126 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
10 | reyssat | 1 | /* Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis |
2 | * |
||
3 | * This program is free software; you can redistribute it and/or modify |
||
4 | * it under the terms of the GNU General Public License as published by |
||
5 | * the Free Software Foundation; either version 2 of the License, or |
||
6 | * (at your option) any later version. |
||
7 | * |
||
8 | * This program is distributed in the hope that it will be useful, |
||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
11 | * GNU General Public License for more details. |
||
12 | * |
||
13 | * You should have received a copy of the GNU General Public License |
||
14 | * along with this program; if not, write to the Free Software |
||
15 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
16 | */ |
||
8160 | bpr | 17 | #include "libwims.h" |
10 | reyssat | 18 | |
19 | static int _lcomp(const void *l1, const void *l2) |
||
20 | { |
||
21 | const double *d1, *d2; |
||
22 | double d; |
||
23 | d1=(const double *) l1; d2=(const double *) l2; |
||
24 | d=*d1-*d2; |
||
25 | if(d<0) return -1; if(d>0) return 1; |
||
26 | return 0; |
||
27 | } |
||
28 | |||
29 | static double lc_scalex(leveldata *ld, int x) |
||
30 | { |
||
31 | if(x<0) x=0; if(x>=ld->xsize) x=ld->xsize-1; |
||
32 | return ld->xspan*((double) x - 0.40127)/ld->xsize+ld->xrange[0]; |
||
33 | } |
||
34 | |||
35 | static double lc_scaley(leveldata *ld, int y) |
||
36 | { |
||
37 | if(y<0) y=0; if(y>=ld->ysize) y=ld->ysize-1; |
||
38 | return -ld->yspan*((double) y - 0.40127)/ld->ysize+ld->yrange[1]; |
||
39 | } |
||
40 | |||
41 | static int _getlevel(leveldata *ld, int x, int y) |
||
42 | { |
||
43 | double dd; |
||
44 | int i; |
||
7840 | bpr | 45 | |
10 | reyssat | 46 | eval_setval(ld->xevpos,lc_scalex(ld,x)); |
47 | eval_setval(ld->yevpos,lc_scaley(ld,y)); |
||
7847 | bpr | 48 | dd=checked_eval(ld->fn); |
10 | reyssat | 49 | for(i=0;i<ld->levelcnt && dd>ld->levels[i];i++); |
50 | return i; |
||
51 | } |
||
52 | |||
53 | static void lc_replacexy(leveldata *ld) |
||
54 | { |
||
55 | char *pp; |
||
56 | for(pp=varchr(ld->fn,ld->xname);pp!=NULL;pp=varchr(pp,ld->xname)) { |
||
7840 | bpr | 57 | string_modify(ld->fn,pp,pp+strlen(ld->xname),EV_X); |
58 | pp+=strlen(EV_X); |
||
10 | reyssat | 59 | } |
60 | for(pp=varchr(ld->fn,ld->yname);pp!=NULL;pp=varchr(pp,ld->yname)) { |
||
7840 | bpr | 61 | string_modify(ld->fn,pp,pp+strlen(ld->yname),EV_Y); |
62 | pp+=strlen(EV_Y); |
||
10 | reyssat | 63 | } |
64 | } |
||
65 | |||
7840 | bpr | 66 | /* produces level curve data. Returns non-zero if error. */ |
10 | reyssat | 67 | int levelcurve(leveldata *ld) |
68 | { |
||
69 | int xx,yy,xi,yi,xsteps,ysteps; |
||
70 | int i,x,y,xt,yt; |
||
71 | short int l1[LEVELSIZE_LIM+16], l2[LEVELSIZE_LIM+16]; |
||
72 | short int l3[LEVELGRAIN_LIM+2][LEVELGRAIN_LIM+2]; |
||
73 | char f[MAX_LINELEN+1]; |
||
7840 | bpr | 74 | |
10 | reyssat | 75 | ld->datacnt=0; |
76 | if(ld->fn==NULL || *(ld->fn)==0 || ld->levelcnt<1) return 1; |
||
77 | if(ld->grain<1) ld->grain=4; |
||
78 | if(ld->grain>LEVELGRAIN_LIM) ld->grain=LEVELGRAIN_LIM; |
||
79 | if(ld->levelcnt>LEVEL_LIM) ld->levelcnt=LEVEL_LIM; |
||
80 | if(ld->xsize<10 || ld->xsize>LEVELSIZE_LIM) return 2; |
||
81 | if(ld->ysize<10 || ld->ysize>LEVELSIZE_LIM) return 2; |
||
82 | if(check_parentheses(ld->fn,0)) return 3; |
||
83 | ld->xspan=ld->xrange[1]-ld->xrange[0]; |
||
84 | ld->yspan=ld->yrange[1]-ld->yrange[0]; |
||
85 | if(ld->levelcnt>1) qsort(ld->levels,ld->levelcnt,sizeof(double),_lcomp); |
||
86 | if(ld->xname==NULL || *(ld->xname)==0) ld->xname="x"; |
||
87 | if(ld->yname==NULL || *(ld->yname)==0) ld->yname="y"; |
||
88 | snprintf(f,sizeof(f),"%s",ld->fn); substitute(f); ld->fn=f; |
||
89 | ld->xevpos=eval_getpos(EV_X); ld->yevpos=eval_getpos(EV_Y); |
||
90 | if(ld->xevpos<0 || ld->yevpos<0) return 4; |
||
91 | lc_replacexy(ld); evalue_compile(f); |
||
92 | xsteps=(ld->xsize+ld->grain-1)/ld->grain+1; |
||
93 | ysteps=(ld->ysize+ld->grain-1)/ld->grain+1; |
||
94 | for(yy=yi=0;yi<ysteps;yy+=ld->grain,yi++) l2[yi]=_getlevel(ld,0,yy); |
||
95 | l2[ysteps]=l2[ysteps-1]; |
||
96 | for(xi=1,xx=ld->grain;xi<xsteps && ld->datacnt<LEVELPOINT_LIM;xx+=ld->grain,xi++) { |
||
7840 | bpr | 97 | memmove(l1,l2,(ysteps+1)*sizeof(short int)); |
98 | for(yi=yy=0;yi<ysteps;yy+=ld->grain,yi++) l2[yi]=_getlevel(ld,xx,yy); |
||
99 | l2[ysteps]=l2[ysteps-1]; |
||
100 | for(yi=0;yi<ysteps && ld->datacnt<LEVELPOINT_LIM;yi++) |
||
101 | if(l1[yi]!=l1[yi+1] || l1[yi]!=l2[yi] || l1[yi]!=l2[yi+1]) { |
||
102 | for(x=0,xt=(xi-1)*ld->grain;x<=ld->grain;x++,xt++) |
||
7847 | bpr | 103 | for(y=0,yt=yi*ld->grain;y<=ld->grain;y++,yt++) { |
7840 | bpr | 104 | if(x==0 && y==0) {l3[x][y]=l1[yi]; continue;} |
105 | if(x==0 && y==ld->grain) {l3[x][y]=l1[yi+1]; continue;} |
||
106 | if(x==ld->grain && y==0) {l3[x][y]=l2[yi]; continue;} |
||
107 | if(x==ld->grain && y==ld->grain) {l3[x][y]=l2[yi+1]; continue;} |
||
108 | l3[x][y]=_getlevel(ld,xt,yt); |
||
7847 | bpr | 109 | } |
7840 | bpr | 110 | for(x=0,xt=(xi-1)*ld->grain;x<ld->grain;x++,xt++) |
7847 | bpr | 111 | for(y=0,yt=yi*ld->grain;y<ld->grain;y++,yt++) { |
7840 | bpr | 112 | i=l3[x][y]; |
113 | if((i!=l3[x][y+1] || i!=l3[x+1][y]) && |
||
114 | ld->datacnt<LEVELPOINT_LIM && |
||
115 | (i!=l3[x][y+1] || ld->datacnt==0 || |
||
116 | l3[x+1][y+1]==l3[x+1][y] || |
||
117 | ld->xdata[ld->datacnt-1]!=xt || |
||
118 | ld->ydata[ld->datacnt-1]!=yt-1)) { |
||
119 | ld->xdata[ld->datacnt]=xt; |
||
120 | ld->ydata[ld->datacnt++]=yt; |
||
121 | } |
||
7847 | bpr | 122 | } |
7840 | bpr | 123 | } |
10 | reyssat | 124 | } |
125 | return 0; |
||
126 | } |
||
127 |