Subversion Repositories wimsdev

Rev

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