/* NB: MAKE SURE YOU EDIT THE TEMPLATE FILE!!!! */ #ifndef FILTER_PTYPE #include #endif #ifndef UNUSED #ifdef __GNUC__ # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) #else # define UNUSED(x) UNUSED_ ## x #endif #endif /* panda and pie incorrectly used astronomical angles. fixed 4/2004 */ #define USE_ASTRO_ANGLE 0 /* we might want to avoid (x86) extended precision problems */ #define USE_FPU_DOUBLE _FPUDBL_ #if USE_FPU_DOUBLE #include static fpu_control_t _cw; #define FPU_DOUBLE {fpu_control_t _cw2; _FPU_GETCW(_cw); _cw2 = _cw & ~_FPU_EXTENDED; _cw2 |= _FPU_DOUBLE; _FPU_SETCW(_cw2);} #define FPU_RESTORE {_FPU_SETCW(_cw);} #else #define FPU_DOUBLE #define FPU_RESTORE #endif /* alternate method of avoiding (x86) extended precision problems */ #define USE_FLOAT_COMPARE 0 /* add this to FilterOpen to cause this module to be loaded for dynamic linking */ static int evregno=0; void initevregions(void) { evregno++; return; } static int polypt(double x, double y, double* poly, int count, double UNUSED(xstart), double ystart, int flag) { /* x-- x value of point being tested */ /* y-- y value of point being tested */ /* poly-- bounding polygon, array of length (count*2) */ /* count-- number of edges of bounding polygon */ /* This algorithm is from "An Introduction to Ray Tracing", Academic Press, */ /* 1989, edited by Andrew Glassner, pg 53 */ /* a point lies in a polygon if a line is extended from the point to infinite */ /* in any direction and the number of intersections with the polygon is odd. */ /* This is valid for both concave and convex polygons. */ /* Points on a vertex are considered inside. */ /* Points on a edge are considered inside. */ /* number of crossings */ int crossings = 0; /* init sign for first vertice */ int sign = ((poly[1] - y)>=0) ? 1 : -1; /* for all edges */ int i; /* if flag is set, we check x, y against first point */ if( flag && (x == poly[0]) && (y == poly[1]) ) return 1; for(i=0; i=0) ? 1 : -1; /* horiz line */ if( (y1==0) && (y2==0) ){ if( ((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0)) ){ /* we always return true for ystart horiz lines */ if( y == ystart ) return 1; else return fmod((double)crossings+1,2.0) ? 1 : 0; } } /* vertical line */ else if( (x1==0) && (x2==0) ){ if( ((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0)) ){ return fmod((double)crossings+1,2.0) ? 1 : 0; } } /* point on line */ else if( feq((y1*(x2-x1)),(x1*(y2-y1))) ){ if( (((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0))) && (((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0))) ){ return fmod((double)crossings+1,2.0) ? 1 : 0; } } #if 0 /* horiz line */ if( (y1==0) && (y2==0) ){ if( ((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0)) ){ if( y == ystart ){ return 1; } } } /* vertical line */ else if( (x1==0) && (x2==0) ){ if( ((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0)) ){ if( x == xstart ){ return 1; } } } /* point on line */ else if( feq((y1*(x2-x1)),(x1*(y2-y1))) ){ if( (((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0))) && (((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0))) ){ return 0; } } #endif if (sign != nextSign) { if (x1>0 && x2>0) crossings++; else if (x1>0 || x2>0) { if (x1-(y1*(x2-x1)/(y2-y1)) > 0) crossings++; } sign = nextSign; } } return crossings%2 ? 1 : 0; /* if odd, point is inside */ } static void quadeq(double a, double b, double c, double *x1, double *x2, int *nr, int *nc) { double dis, q; if( feq(a,0.0) ){ *nc = 0; if( feq(b,0.0) ){ *nr = 0; *x1 = 0.0; } else{ *nr = 1; *x1 = -c / b; } *x2 = *x1; } else{ dis = b*b - 4.0 * a * c; if( dis > 0.0 ){ *nr = 2; *nc = 0; dis = sqrt(dis); if( b < 0.0 ) dis = -dis; q = -0.5 * (b + dis); *x1 = q/a; *x2 = c/q; if(*x1 > *x2){ q = *x1; *x1 = *x2; *x2 = q; } } else if( feq(dis,0.0) ){ *nr = 1; *nc = 0; *x1 = - 0.5 * b / a; *x2 = *x1; } else{ *nr = 0; *nc = 2; *x1 = - 0.5 * b / a; *x2 = 0.5 * sqrt(-dis) / a; } } } static int corner_vertex(int index, int width, int height, double *x, double *y) { switch (index) { case 1: *x = 0.0; *y = height + 1; break; case 2: *x = 0.0; *y = 0.0; break; case 3: *x = width + 1; *y = 0.0; break; case 4: *x = width + 1; *y = height + 1; default: break; } index = index + 1; if(index > 4) index = 1; return(index); } static int pie_intercept(double width, double height, double xcen, double ycen, double angle, double *xcept, double *ycept) { double angl, slope; /* l: angle and slope of ray */ angl = angle; /* put angles in normal range */ while (angl < 0.0) angl = angl + 360.0; while (angl >= 360.0) angl = angl - 360.0; /* check for a horizontal angle */ #if USE_ASTRO_ANGLE if(fabs(angl - 90.0) < SMALL_NUMBER) { #else if(fabs(angl - 180.0) < SMALL_NUMBER) { #endif *xcept = 0.0; *ycept = ycen; return(2); } #if USE_ASTRO_ANGLE if(fabs(angl - 270.0) < SMALL_NUMBER) { #else if(fabs(angl - 0.0) < SMALL_NUMBER) { #endif *xcept = width + 1; *ycept = ycen; return(4); } /* convert to a Cartesian angle */ #if USE_ASTRO_ANGLE angl = angl + 90.0; #endif if(angl >= 360.0) angl = angl - 360.0; if(angl < 180.0) { *ycept = height + 1; /* rule out vertical line */ if(fabs(angl - 90.0) < SMALL_NUMBER) { *xcept = xcen; return(1); } } else { *ycept = 0.0; /* rule out vertical line */ if(fabs(angl - 270.0) < SMALL_NUMBER) { *xcept = xcen; return(3); } } /* convert to radians */ angl = (angl / 180.0) * M_PI; /* calculate slope */ slope = tan(angl); /* calculate intercept with designated y edge */ *xcept = xcen + ((*ycept - ycen) / slope); if(*xcept < 0) { *ycept = (ycen - (xcen * slope)); *xcept = 0.0; return(2); } else if(*xcept > (width + 1)) { *ycept = (ycen + ((width + 1 - xcen) * slope)); *xcept = width + 1; return(4); } else { if(*ycept < height) return(3); else return(1); } } /* ***************************** shapes ********************************** */ int evannulus(GFilt g, int rno, int sno, int flag, int type, double x, double y, double xcen, double ycen, double ri, double ro) { /* use circle if possible */ if( ri == 0 ){ return(evcircle(g, rno, sno, flag, type, x, y, xcen, ycen, ro)); } if( !g->shapes[sno].init ){ g->shapes[sno].init = 1; g->shapes[sno].ystart = ycen - ro; g->shapes[sno].ystop = ycen + ro; g->shapes[sno].r1sq = ri * ri; g->shapes[sno].r2sq = ro * ro; } if((((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && (((xcen-x)*(xcen-x))+((ycen-y)*(ycen-y))<=g->shapes[sno].r2sq) && (((xcen-x)*(xcen-x))+((ycen-y)*(ycen-y))>g->shapes[sno].r1sq)) == flag ){ if( rno && flag ) g->rid = rno; return 1; } else{ return 0; } } int evbox(GFilt g, int rno, int sno, int flag, int UNUSED(type), double x, double y, double xcen, double ycen, double xwidth, double yheight, double angle) { int i; double angl; /* l: Cartesian angle in radians */ double half_width, half_height;/* l: radii (1/2 width and height) */ double cosangl, sinangl; /* l: sine, cosine of the Cartesian angle */ double hw_cos, hw_sin; /* l: products of half_width with sin, cos */ double hh_cos, hh_sin; /* l: products of half_height with sin, cos */ double xstart=0.0; if( (xwidth == 0) && (yheight==0) ){ return(!flag); } if( !g->shapes[sno].init ){ g->shapes[sno].init = 1; #if USE_ASTRO_ANGLE /* convert to a Cartesian angle; save angle for use in multi or slices */ angl = angle + 90.0; #else angl = angle; #endif while (angl >= 360.0) angl = angl - 360.0; /* convert to radians */ angl = (angl / 180.0) * M_PI; sinangl = sin (angl); cosangl = cos (angl); #if USE_ASTRO_ANGLE /* since we rotate by 90.0 degrees to get from astro angle to cartesian, */ /* we also need to switch the width and height. we do this secretly so */ /* that the display will turn out right, by doing it in the half terms */ half_width = yheight / 2.0; half_height = xwidth / 2.0; #else half_width = xwidth / 2.0; half_height = yheight / 2.0; #endif hw_cos = half_width * cosangl; hw_sin = half_width * sinangl; hh_cos = half_height * cosangl; hh_sin = half_height * sinangl; g->shapes[sno].pts = (double *)calloc(8, sizeof(double)); #if USE_ASTRO_ANGLE g->shapes[sno].pts[0] = xcen - hw_cos - hh_sin; g->shapes[sno].pts[1] = ycen - hw_sin + hh_cos; g->shapes[sno].pts[2] = xcen + hw_cos - hh_sin; g->shapes[sno].pts[3] = ycen + hw_sin + hh_cos; g->shapes[sno].pts[4] = xcen + hw_cos + hh_sin; g->shapes[sno].pts[5] = ycen + hw_sin - hh_cos; g->shapes[sno].pts[6] = xcen - hw_cos + hh_sin; g->shapes[sno].pts[7] = ycen - hw_sin - hh_cos; #else g->shapes[sno].pts[0] = xcen - hw_cos + hh_sin; g->shapes[sno].pts[1] = ycen - hh_cos - hw_sin; g->shapes[sno].pts[2] = xcen - hw_cos - hh_sin; g->shapes[sno].pts[3] = ycen + hh_cos - hw_sin; g->shapes[sno].pts[4] = xcen + hw_cos - hh_sin; g->shapes[sno].pts[5] = ycen + hh_cos + hw_sin; g->shapes[sno].pts[6] = xcen + hw_cos + hh_sin; g->shapes[sno].pts[7] = ycen - hh_cos + hw_sin; #endif g->shapes[sno].npt = 8; /* now find the y limits */ if( g->shapes[sno].npt ){ xstart = g->shapes[sno].pts[0]; g->shapes[sno].ystart = g->shapes[sno].pts[1]; g->shapes[sno].ystop = g->shapes[sno].ystart; for(i=1; ishapes[sno].npt; i+=2){ if(g->shapes[sno].pts[i-1] < xstart) xstart = g->shapes[sno].pts[i-1]; if(g->shapes[sno].pts[i] > g->shapes[sno].ystop) g->shapes[sno].ystop = g->shapes[sno].pts[i]; if(g->shapes[sno].pts[i] < g->shapes[sno].ystart) g->shapes[sno].ystart = g->shapes[sno].pts[i]; } } } if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && polypt(x, y, g->shapes[sno].pts, g->shapes[sno].npt/2, xstart, g->shapes[sno].ystart, 0)) == flag ){ if( rno && flag ) g->rid = rno; return 1; } else return 0; } int evcircle(GFilt g, int rno, int sno, int flag, int UNUSED(type), double x, double y, double xcen, double ycen, double radius) { if( radius == 0 ){ return(!flag); } if( !g->shapes[sno].init ){ g->shapes[sno].init = 1; g->shapes[sno].ystart = ycen - radius; g->shapes[sno].ystop = ycen + radius; g->shapes[sno].r1sq = radius * radius; } if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && (((xcen-x)*(xcen-x))+((ycen-y)*(ycen-y))<=g->shapes[sno].r1sq)) == flag ){ if( rno && flag ) g->rid = rno; return 1; } else return 0; } int evellipse(GFilt g, int rno, int sno, int flag, int type, double x, double y, double xcen, double ycen, double xrad, double yrad, double angle) { double yhi, yoff; double b, c; double b_partial, c_partial; double xboff, xfoff; int nr, nc; /* use circle if possible */ if( xrad == yrad ){ return(evcircle(g, rno, sno, flag, type, x, y, xcen, ycen, xrad)); } if( !g->shapes[sno].init ){ g->shapes[sno].init = 1; /* set worst case limits (xrad axis parallel to vertical axis) */ #if USE_ASTRO_ANGLE /* convert to a Cartesian angle; save "angle" for use by other routines */ g->shapes[sno].angl = angle + 90.0; #else g->shapes[sno].angl = angle; #endif while( g->shapes[sno].angl >= 360.0 ) g->shapes[sno].angl = g->shapes[sno].angl - 360.0; /* convert to radians */ g->shapes[sno].angl = (g->shapes[sno].angl / 180.0) * M_PI; g->shapes[sno].sinangl = sin(g->shapes[sno].angl); g->shapes[sno].cosangl = cos(g->shapes[sno].angl); /* calculate approximate y limits */ /* choose lesser of containing rotbox and circle */ #if USE_ASTRO_ANGLE yhi = fabs(g->shapes[sno].sinangl * yrad) + fabs(g->shapes[sno].cosangl * xrad); #else yhi = fabs(g->shapes[sno].sinangl * xrad) + fabs(g->shapes[sno].cosangl * yrad); #endif yhi = min(yhi, max(yrad, xrad)); g->shapes[sno].ystart = ycen - yhi; g->shapes[sno].ystop = ycen + yhi; /* prepare partials for quadratic equation solutions to coordinates */ g->shapes[sno].cossq = g->shapes[sno].cosangl * g->shapes[sno].cosangl; g->shapes[sno].sinsq = g->shapes[sno].sinangl * g->shapes[sno].sinangl; #if USE_ASTRO_ANGLE /* because we rotate by 90.0 degrees to get from astro angle to */ /* cartesian, we also need to switch the x and y axes. we do this */ /* secretly so that the display will turn out right, by doing it in */ /* the sq terms */ g->shapes[sno].xradsq = yrad * yrad; g->shapes[sno].yradsq = xrad * xrad; #else g->shapes[sno].xradsq = xrad * xrad; g->shapes[sno].yradsq = yrad * yrad; #endif /* fill in as much of a,b,c as we can */ g->shapes[sno].a = (g->shapes[sno].cossq / g->shapes[sno].xradsq) + (g->shapes[sno].sinsq / g->shapes[sno].yradsq); } if( ((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) ){ b_partial = (2.0 * g->shapes[sno].sinangl) * ((g->shapes[sno].cosangl / g->shapes[sno].xradsq) - (g->shapes[sno].cosangl / g->shapes[sno].yradsq)); c_partial = (g->shapes[sno].sinsq / g->shapes[sno].xradsq) + (g->shapes[sno].cossq / g->shapes[sno].yradsq); yoff = y - ycen; b = b_partial * yoff; c = (c_partial * yoff * yoff) - 1.0; /* solve quadratic */ quadeq (g->shapes[sno].a, b, c, &xboff, &xfoff, &nr, &nc); /* if real roots */ if( nr != 0 ) { FPU_DOUBLE #if USE_FLOAT_COMPARE if( (((float)x>=(float)(xcen+xboff)) && ((float)x<=(float)(xcen+xfoff))) == flag ){ #else if( ((x>=(xcen+xboff)) && (x<=(xcen+xfoff))) == flag ){ #endif if( rno && flag ) g->rid = rno; FPU_RESTORE return 1; } else{ FPU_RESTORE return 0; } } else return !flag; } return !flag; } int evfield(GFilt g, int rno, int UNUSED(sno), int flag, int UNUSED(type), double UNUSED(x), double UNUSED(y)) { if( flag ){ if( rno && flag ) g->rid = rno; return 1; } else return 0; } int evline(GFilt g, int rno, int sno, int flag, int UNUSED(type), double x, double y, double x1, double y1, double x2, double y2) { if( !g->shapes[sno].init ){ g->shapes[sno].init = 1; g->shapes[sno].ystart = min(y1,y2); g->shapes[sno].ystop = max(y1,y2); g->shapes[sno].x1 = x1; g->shapes[sno].x2 = x2; g->shapes[sno].y1 = y1; if( feq(y1,y2) ){ g->shapes[sno].xonly = 1; g->shapes[sno].invslope = 0; } else{ g->shapes[sno].xonly = 0; g->shapes[sno].invslope = (x1 - x2) / (y1 - y2); } } if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && ((!g->shapes[sno].xonly && feq((((y-g->shapes[sno].y1)*g->shapes[sno].invslope)+g->shapes[sno].x1),x)) || (g->shapes[sno].xonly && ((x>=g->shapes[sno].x1)&&(x<=g->shapes[sno].x2))))) == flag){ if( rno && flag ) g->rid = rno; return 1; } else return 0; } int evpie(GFilt g, int rno, int sno, int flag, int type, double x, double y, double xcen, double ycen, double angle1, double angle2) { int i; int width, height; /* l: image mask width and height */ double sweep; /* l: sweep between cut angles */ int intrcpt1, intrcpt2; /* l: side intercepted by each cut */ double x2, y2; /* l: coordinates of second intercept */ double xstart=0.0; /* use field if possible */ if( (angle1==0) && (angle2==360) ){ return(evfield(g, rno, sno, flag, type, x, y)); } if( !g->shapes[sno].init ){ g->shapes[sno].init = 1; /* we have to fake width and height, since we do not know them! */ width = LARGE_NUMBER; height = LARGE_NUMBER; /* start listing vertices of polygon */ g->shapes[sno].pts = (double *)calloc(14, sizeof(double)); g->shapes[sno].pts[0] = xcen; g->shapes[sno].pts[1] = ycen; sweep = angle2 - angle1; /* if sweep is too small to be noticed, don't bother */ if(fabs(sweep) < SMALL_NUMBER) return !flag; if (sweep < 0.0) sweep = sweep + 360.0; intrcpt1 = pie_intercept((double)width, (double)height, xcen, ycen, angle1, &(g->shapes[sno].pts[2]), &(g->shapes[sno].pts[3])); intrcpt2 = pie_intercept((double)width, (double)height, xcen, ycen, angle2, &x2, &y2); g->shapes[sno].npt = 4; /* if angles intercept same side and slice is between them, no corners */ /* else, mark corners until reaching side with second angle intercept */ if((intrcpt1 != intrcpt2) || (sweep > 180.0)){ do{ intrcpt1 = corner_vertex(intrcpt1, width, height, &(g->shapes[sno].pts[g->shapes[sno].npt]), &(g->shapes[sno].pts[g->shapes[sno].npt+1])); g->shapes[sno].npt = g->shapes[sno].npt + 2; }while(intrcpt1 != intrcpt2); } g->shapes[sno].pts[g->shapes[sno].npt] = x2; g->shapes[sno].pts[g->shapes[sno].npt+1] = y2; g->shapes[sno].npt = g->shapes[sno].npt + 2; /* now find the y limits */ if( g->shapes[sno].npt ){ xstart = g->shapes[sno].pts[0]; g->shapes[sno].ystart = g->shapes[sno].pts[1]; g->shapes[sno].ystop = g->shapes[sno].ystart; for(i=1; ishapes[sno].npt; i+=2){ if(g->shapes[sno].pts[i-1] < xstart) xstart = g->shapes[sno].pts[i-1]; if(g->shapes[sno].pts[i] > g->shapes[sno].ystop) g->shapes[sno].ystop = g->shapes[sno].pts[i]; if(g->shapes[sno].pts[i] < g->shapes[sno].ystart) g->shapes[sno].ystart = g->shapes[sno].pts[i]; } } } if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && polypt(x, y, g->shapes[sno].pts, g->shapes[sno].npt/2, xstart, g->shapes[sno].ystart, 1)) == flag ){ if( rno && flag ) g->rid = rno; return 1; } else{ return 0; } } int evqtpie(GFilt g, int rno, int sno, int flag, int type, double x, double y, double xcen, double ycen, double angle1, double angle2) { return evpie(g, rno, sno, flag, type, x, y, xcen, ycen, angle1, angle2); } int evpoint(GFilt g, int rno, int UNUSED(sno), int flag, int UNUSED(type), double x, double y, double xcen, double ycen) { if( ((x==xcen) && (y==ycen)) == flag ){ if( rno && flag ) g->rid = rno; return 1; } else return 0; } #ifdef __STDC__ int evpolygon(GFilt g, int rno, int sno, int flag, int UNUSED(type), double x, double y, ...) { int i, maxpts; double xstart=0.0; va_list args; va_start(args, y); #else int evpolygon(va_alist) va_dcl { GFilt g; int rno, sno, flag, type; double x, y; double xstart=0.0; int i, maxpts; va_list args; va_start(args); g = va_arg(args, GFilt); rno = va_arg(args, int); sno = va_arg(args, int); flag = va_arg(args, int); type = va_arg(args, int); x = va_arg(args, double); y = va_arg(args, double); #endif if( !g->shapes[sno].init ){ g->shapes[sno].init = 1; /* allocate space for x,y arguments */ maxpts = MASKINC; g->shapes[sno].pts = (double *)calloc(maxpts, sizeof(double)); /* gather up arguments */ g->shapes[sno].npt = 0; while( 1 ){ if( g->shapes[sno].npt >= maxpts ){ maxpts += MASKINC; g->shapes[sno].pts = (double *)realloc(g->shapes[sno].pts, maxpts*sizeof(double)); } g->shapes[sno].pts[g->shapes[sno].npt] = va_arg(args, double); /* two negatives in a row means we are at end of args */ if( feq(g->shapes[sno].pts[g->shapes[sno].npt],PSTOP) && feq(g->shapes[sno].pts[g->shapes[sno].npt-1],PSTOP) ){ g->shapes[sno].npt--; break; } g->shapes[sno].npt++; } va_end(args); /* realloc to actual size */ g->shapes[sno].pts = (double *)realloc(g->shapes[sno].pts, g->shapes[sno].npt*sizeof(double)); /* now find the y limits */ if( g->shapes[sno].npt ){ xstart = g->shapes[sno].pts[0]; g->shapes[sno].ystart = g->shapes[sno].pts[1]; g->shapes[sno].ystop = g->shapes[sno].ystart; for(i=1; ishapes[sno].npt; i+=2){ if(g->shapes[sno].pts[i-1] < xstart) xstart = g->shapes[sno].pts[i-1]; if(g->shapes[sno].pts[i] > g->shapes[sno].ystop) g->shapes[sno].ystop = g->shapes[sno].pts[i]; if(g->shapes[sno].pts[i] < g->shapes[sno].ystart) g->shapes[sno].ystart = g->shapes[sno].pts[i]; } } } if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && polypt(x, y, g->shapes[sno].pts, g->shapes[sno].npt/2, xstart, g->shapes[sno].ystart, 0)) == flag ){ if( rno && flag ) g->rid = rno; return 1; } else return 0; } /* accelerator regions -- lower and upper limits are given for n regions */ int evnannulus(GFilt g, int rno, int sno, int flag, int type, double x, double y, double xcen, double ycen, double lo, double hi, int n) { int i; int xsno; double dinc; /* get limits */ dinc = (hi - lo)/(double)n; xsno = (g->nshapes+1)+((sno-1)*XSNO); if( flag ){ /* if its not somewhere inside the entire region we lose ... */ if( !evannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){ return(0); } /* look through all of them to find the right one */ for(i=0; inshapes+1)+((sno-1)*XSNO); if( flag ){ /* if its not somewhere inside the entire region we lose ... */ if( !evbox(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){ return(0); } /* if its in the inner region we lose */ if( evbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){ return(0); } /* look through all of them to find the right one */ for(i=0; inshapes+1)+((sno-1)*XSNO); if( flag ){ /* if its not somewhere inside the entire region we lose ... */ if( !evellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){ return(0); } /* if its in the inner region we lose */ if( evellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){ return(0); } /* look through all of them to find the right one */ for(i=0; i hi ) lo -= 360.0; dinc = (hi - lo)/n; xsno = (g->nshapes+1)+((sno-1)*XSNO); if( flag ){ /* check limits */ if( !evpie(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){ return(0); } /* look through all of them to find the right one */ for(i=0; inshapes+1)+((sno-1)*XSNO); if( flag ){ /* if its not somewhere inside the entire region we lose ... */ if( !evannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, radlo, radhi) || !evpie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi) ){ return(0); } /* look through all of them to find the right one */ for(a=1; a<=ahi; a++){ for(r=1; r<=rhi; r++){ if( evannulus(g, rno+n, sno+(2*n), flag, type, x, y, xcen, ycen, radlo+((r-1)*rinc), radlo+(r*rinc)) && evpie(g, rno+n, sno+(2*n+1), flag, type, x, y, xcen, ycen, anglo+((a-1)*ainc), anglo+(a*ainc)) ){ return(1); } n++; } } return(0); } else{ /* if its not somewhere inside the entire region we win ... */ if( !evannulus(g, 0, xsno, 1, type, x, y, xcen, ycen, radlo, radhi) ) return(1); else if( !evpie(g, 0, xsno+1, 1, type, x, y, xcen, ycen, anglo, anghi) ){ return(1); } else{ return(0); } } } int evbpanda(GFilt g, int rno, int sno, int flag, int type, double x, double y, double xcen, double ycen, double anglo, double anghi, double angn, double xlo, double ylo, double xhi, double yhi, double radn, double ang) { int a, r; int ahi, rhi; int xsno; int n=0; double ainc, xinc, yinc; /* get limits */ anglo += ang; anghi += ang; ainc = (anghi - anglo)/angn; ahi = (int)angn; xinc = (xhi - xlo)/radn; yinc = (yhi - ylo)/radn; rhi = (int)radn; xsno = (g->nshapes+1)+((sno-1)*XSNO); if( flag ){ /* if its not somewhere inside the entire region we lose ... */ if( !evbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, ang) ){ return(0); } /* but if its in the inner region we lose */ else if( evbox(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, ang) ){ return(0); } /* its in the box .. must also be in the pie */ else if( !evpie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){ return(0); } /* look through all of them to find the right one */ for(a=0; anshapes+1)+((sno-1)*XSNO); if( flag ){ /* if its not somewhere inside the entire region we lose ... */ if( !evellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, ang) ){ return(0); } /* but if its in the inner region we lose */ else if( evellipse(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, ang) ){ return(0); } /* its in the ellipse .. must also be in the pie */ else if( !evpie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){ return(0); } /* look through all of them to find the right one */ for(a=0; anshapes+1)+((sno-1)*XSNO); if( !g->shapes[xsno].xv ){ maxpts = MASKINC; g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); g->shapes[xsno].nv = 0; while( 1 ){ if( g->shapes[xsno].nv >= maxpts ){ maxpts += MASKINC; g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, maxpts*sizeof(double)); } g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ g->shapes[xsno].nv--; break; } g->shapes[xsno].nv++; } va_end(args); g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, g->shapes[xsno].nv*sizeof(double)); } n = g->shapes[xsno].nv; xv = g->shapes[xsno].xv; /* this should be impossible ... */ if( n == 2 ){ return(evannulus(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1])); } if( flag ){ /* if its not somewhere inside the entire region we lose ... */ if( !evannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){ return(0); } /* look through all of them to find the right one */ for(i=0; inshapes+1)+((sno-1)*XSNO); if( !g->shapes[xsno].xv ){ maxpts = MASKINC; g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); g->shapes[xsno].nv = 0; while( 1 ){ if( g->shapes[xsno].nv >= maxpts ){ maxpts += MASKINC; g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, maxpts*sizeof(double)); } g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ g->shapes[xsno].nv--; break; } g->shapes[xsno].nv++; } va_end(args); g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, g->shapes[xsno].nv*sizeof(double)); } n = g->shapes[xsno].nv; xv = g->shapes[xsno].xv; ang = xv[--n]; /* this should be impossible ... */ if( n == 2 ){ return(evbox(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang)); } if( flag ){ /* if its not somewhere inside the entire region we lose ... */ if( !evbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], ang) ){ return(0); } /* if its in the inner region we lose */ if( evbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang) ){ return(0); } /* look through all of them to find the right one */ for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); if( !g->shapes[xsno].xv ){ maxpts = MASKINC; g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); g->shapes[xsno].nv = 0; while( 1 ){ if( g->shapes[xsno].nv >= maxpts ){ maxpts += MASKINC; g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, maxpts*sizeof(double)); } g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ g->shapes[xsno].nv--; break; } g->shapes[xsno].nv++; } va_end(args); g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, g->shapes[xsno].nv*sizeof(double)); } n = g->shapes[xsno].nv; xv = g->shapes[xsno].xv; ang = xv[--n]; /* this should be impossible ... */ if( n == 2 ){ return(evellipse(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang)); } if( flag ){ /* if its not somewhere inside the entire region we lose ... */ if( !evellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], ang) ){ return(0); } /* if its in the inner region we lose */ if( evellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang) ){ return(0); } /* look through all of them to find the right one */ for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); if( !g->shapes[xsno].xv ){ maxpts = MASKINC; g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); g->shapes[xsno].nv = 0; while( 1 ){ if( g->shapes[xsno].nv >= maxpts ){ maxpts += MASKINC; g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, maxpts*sizeof(double)); } g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ g->shapes[xsno].nv--; break; } g->shapes[xsno].nv++; } va_end(args); g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, g->shapes[xsno].nv*sizeof(double)); } n = g->shapes[xsno].nv; xv = g->shapes[xsno].xv; /* this should be impossible ... */ if( n == 2 ){ return(evpie(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1])); } if( flag ){ /* if its not somewhere inside the entire region we lose ... */ if( !evpie(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){ return(0); } /* look through all of them to find the right one */ for(i=0; inshapes+1)+((sno-1)*XSNO); if( !g->shapes[xsno].xv ){ maxpts = MASKINC; g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); g->shapes[xsno].nv = 0; while( 1 ){ if( g->shapes[xsno].nv >= maxpts ){ maxpts += MASKINC; g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, maxpts*sizeof(double)); } g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ g->shapes[xsno].nv--; break; } g->shapes[xsno].nv++; } va_end(args); g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, g->shapes[xsno].nv*sizeof(double)); } n = g->shapes[xsno].nv; xv = g->shapes[xsno].xv; /* look through all of them to find the right one */ for(i=0, j=0; i