Subversion Repositories wimsdev

Rev

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
    const double *d1, *d2;
21
  const double *d1, *d2;
22
    double d;
22
  double d;
23
    d1=(const double *) l1; d2=(const double *) l2;
23
  d1=(const double *) l1; d2=(const double *) l2;
24
    d=*d1-*d2;
24
  d=*d1-*d2;
25
    if(d<0) return -1;
25
  if(d<0) return -1;
26
    if(d>0) return 1;
26
  if(d>0) return 1;
27
    return 0;
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
    if(x<0) x=0;
32
  if(x<0) x=0;
33
    if(x>=ld->xsize) x=ld->xsize-1;
33
  if(x>=ld->xsize) x=ld->xsize-1;
34
    return ld->xspan*((double) x - 0.40127)/ld->xsize+ld->xrange[0];
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
    if(y<0) y=0;
39
  if(y<0) y=0;
40
    if(y>=ld->ysize) y=ld->ysize-1;
40
  if(y>=ld->ysize) y=ld->ysize-1;
41
    return -ld->yspan*((double) y - 0.40127)/ld->ysize+ld->yrange[1];
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
    double dd;
46
  double dd;
47
    int i;
47
  int i;
48
 
48
 
49
    eval_setval(ld->xevpos,lc_scalex(ld,x));
49
  eval_setval(ld->xevpos,lc_scalex(ld,x));
50
    eval_setval(ld->yevpos,lc_scaley(ld,y));
50
  eval_setval(ld->yevpos,lc_scaley(ld,y));
51
    dd=checked_eval(ld->fn);
51
  dd=checked_eval(ld->fn);
52
    for(i=0;i<ld->levelcnt && dd>ld->levels[i];i++);
52
  for(i=0;i<ld->levelcnt && dd>ld->levels[i];i++);
53
    return i;
53
  return i;
54
}
54
}
55
 
55
 
56
static void lc_replacexy(leveldata *ld)
56
static void lc_replacexy(leveldata *ld)
57
{
57
{
58
    char *pp;
58
  char *pp;
59
    for(pp=varchr(ld->fn,ld->xname);pp!=NULL;pp=varchr(pp,ld->xname)) {
59
  for(pp=varchr(ld->fn,ld->xname);pp!=NULL;pp=varchr(pp,ld->xname)) {
60
      string_modify(ld->fn,pp,pp+strlen(ld->xname),EV_X);
60
    string_modify(ld->fn,pp,pp+strlen(ld->xname),EV_X);
61
      pp+=strlen(EV_X);
61
    pp+=strlen(EV_X);
62
    }
62
  }
63
    for(pp=varchr(ld->fn,ld->yname);pp!=NULL;pp=varchr(pp,ld->yname)) {
63
  for(pp=varchr(ld->fn,ld->yname);pp!=NULL;pp=varchr(pp,ld->yname)) {
64
      string_modify(ld->fn,pp,pp+strlen(ld->yname),EV_Y);
64
    string_modify(ld->fn,pp,pp+strlen(ld->yname),EV_Y);
65
      pp+=strlen(EV_Y);
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
    int xx,yy,xi,yi,xsteps,ysteps;
72
  int xx,yy,xi,yi,xsteps,ysteps;
73
    int i,x,y,xt,yt;
73
  int i,x,y,xt,yt;
74
    short int l1[LEVELSIZE_LIM+16], l2[LEVELSIZE_LIM+16];
74
  short int l1[LEVELSIZE_LIM+16], l2[LEVELSIZE_LIM+16];
75
    short int l3[LEVELGRAIN_LIM+2][LEVELGRAIN_LIM+2];
75
  short int l3[LEVELGRAIN_LIM+2][LEVELGRAIN_LIM+2];
76
    char f[MAX_LINELEN+1];
76
  char f[MAX_LINELEN+1];
77
 
77
 
78
    ld->datacnt=0;
78
  ld->datacnt=0;
79
    if(ld->fn==NULL || *(ld->fn)==0 || ld->levelcnt<1) return 1;
79
  if(ld->fn==NULL || *(ld->fn)==0 || ld->levelcnt<1) return 1;
80
    if(ld->grain<1) ld->grain=4;
80
  if(ld->grain<1) ld->grain=4;
81
    if(ld->grain>LEVELGRAIN_LIM) ld->grain=LEVELGRAIN_LIM;
81
  if(ld->grain>LEVELGRAIN_LIM) ld->grain=LEVELGRAIN_LIM;
82
    if(ld->levelcnt>LEVEL_LIM) ld->levelcnt=LEVEL_LIM;
82
  if(ld->levelcnt>LEVEL_LIM) ld->levelcnt=LEVEL_LIM;
83
    if(ld->xsize<10 || ld->xsize>LEVELSIZE_LIM) return 2;
83
  if(ld->xsize<10 || ld->xsize>LEVELSIZE_LIM) return 2;
84
    if(ld->ysize<10 || ld->ysize>LEVELSIZE_LIM) return 2;
84
  if(ld->ysize<10 || ld->ysize>LEVELSIZE_LIM) return 2;
85
    if(check_parentheses(ld->fn,0)) return 3;
85
  if(check_parentheses(ld->fn,0)) return 3;
86
    ld->xspan=ld->xrange[1]-ld->xrange[0];
86
  ld->xspan=ld->xrange[1]-ld->xrange[0];
87
    ld->yspan=ld->yrange[1]-ld->yrange[0];
87
  ld->yspan=ld->yrange[1]-ld->yrange[0];
88
    if(ld->levelcnt>1) qsort(ld->levels,ld->levelcnt,sizeof(double),_lcomp);
88
  if(ld->levelcnt>1) qsort(ld->levels,ld->levelcnt,sizeof(double),_lcomp);
89
    if(ld->xname==NULL || *(ld->xname)==0) ld->xname="x";
89
  if(ld->xname==NULL || *(ld->xname)==0) ld->xname="x";
90
    if(ld->yname==NULL || *(ld->yname)==0) ld->yname="y";
90
  if(ld->yname==NULL || *(ld->yname)==0) ld->yname="y";
91
    snprintf(f,sizeof(f),"%s",ld->fn); substitute(f); ld->fn=f;
91
  snprintf(f,sizeof(f),"%s",ld->fn); substitute(f); ld->fn=f;
92
    ld->xevpos=eval_getpos(EV_X); ld->yevpos=eval_getpos(EV_Y);
92
  ld->xevpos=eval_getpos(EV_X); ld->yevpos=eval_getpos(EV_Y);
93
    if(ld->xevpos<0 || ld->yevpos<0) return 4;
93
  if(ld->xevpos<0 || ld->yevpos<0) return 4;
94
    lc_replacexy(ld); evalue_compile(f);
94
  lc_replacexy(ld); evalue_compile(f);
95
    xsteps=(ld->xsize+ld->grain-1)/ld->grain+1;
95
  xsteps=(ld->xsize+ld->grain-1)/ld->grain+1;
96
    ysteps=(ld->ysize+ld->grain-1)/ld->grain+1;
96
  ysteps=(ld->ysize+ld->grain-1)/ld->grain+1;
97
    for(yy=yi=0;yi<ysteps;yy+=ld->grain,yi++) l2[yi]=_getlevel(ld,0,yy);
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
      for(yi=0;yi<ysteps && ld->datacnt<LEVELPOINT_LIM;yi++)
103
    for(yi=0;yi<ysteps && ld->datacnt<LEVELPOINT_LIM;yi++)
104
        if(l1[yi]!=l1[yi+1] || l1[yi]!=l2[yi] || l1[yi]!=l2[yi+1]) {
104
      if(l1[yi]!=l1[yi+1] || l1[yi]!=l2[yi] || l1[yi]!=l2[yi+1]) {
105
            for(x=0,xt=(xi-1)*ld->grain;x<=ld->grain;x++,xt++)
105
        for(x=0,xt=(xi-1)*ld->grain;x<=ld->grain;x++,xt++)
106
              for(y=0,yt=yi*ld->grain;y<=ld->grain;y++,yt++) {
106
          for(y=0,yt=yi*ld->grain;y<=ld->grain;y++,yt++) {
107
                if(x==0 && y==0) {l3[x][y]=l1[yi]; continue;}
107
            if(x==0 && y==0) {l3[x][y]=l1[yi]; continue;}
108
                if(x==0 && y==ld->grain) {l3[x][y]=l1[yi+1]; continue;}
108
            if(x==0 && y==ld->grain) {l3[x][y]=l1[yi+1]; continue;}
109
                if(x==ld->grain && y==0) {l3[x][y]=l2[yi]; continue;}
109
            if(x==ld->grain && y==0) {l3[x][y]=l2[yi]; continue;}
110
                if(x==ld->grain && y==ld->grain) {l3[x][y]=l2[yi+1]; continue;}
110
            if(x==ld->grain && y==ld->grain) {l3[x][y]=l2[yi+1]; continue;}
111
                l3[x][y]=_getlevel(ld,xt,yt);
111
            l3[x][y]=_getlevel(ld,xt,yt);
112
              }
112
          }
113
            for(x=0,xt=(xi-1)*ld->grain;x<ld->grain;x++,xt++)
113
        for(x=0,xt=(xi-1)*ld->grain;x<ld->grain;x++,xt++)
114
              for(y=0,yt=yi*ld->grain;y<ld->grain;y++,yt++) {
114
          for(y=0,yt=yi*ld->grain;y<ld->grain;y++,yt++) {
115
                i=l3[x][y];
115
            i=l3[x][y];
116
                if((i!=l3[x][y+1] || i!=l3[x+1][y]) &&
116
            if((i!=l3[x][y+1] || i!=l3[x+1][y]) &&
117
                   ld->datacnt<LEVELPOINT_LIM &&
117
                ld->datacnt<LEVELPOINT_LIM &&
118
                   (i!=l3[x][y+1] || ld->datacnt==0 ||
118
                (i!=l3[x][y+1] || ld->datacnt==0 ||
119
                  l3[x+1][y+1]==l3[x+1][y] ||
119
                l3[x+1][y+1]==l3[x+1][y] ||
120
                  ld->xdata[ld->datacnt-1]!=xt ||
120
                ld->xdata[ld->datacnt-1]!=xt ||
121
                  ld->ydata[ld->datacnt-1]!=yt-1)) {
121
                ld->ydata[ld->datacnt-1]!=yt-1)) {
122
                  ld->xdata[ld->datacnt]=xt;
122
              ld->xdata[ld->datacnt]=xt;
123
                  ld->ydata[ld->datacnt++]=yt;
123
              ld->ydata[ld->datacnt++]=yt;
124
                }
124
            }
125
              }
125
          }
126
        }
126
      }
127
    }
127
  }
128
    return 0;
128
  return 0;
129
}
129
}
130
 
-