Esempio n. 1
0
/*------------------------------------------------------------------------------
  Main program.
*/
int main(int argc, char *argv[])
{
    int ifile, nfiles, np, npoly, npolys,i;
    polygon **poly;
    poly=poly_global;

    /* parse arguments */
    parse_args(argc, argv);

    /* at least one input and output filename required as arguments */
    if (argc - optind < 2) {
	if (optind > 1 || argc - optind >= 1) {
            fprintf(stderr, "%s requires at least 2 arguments: polygon_infile, and outfile\n", argv[0]);
	    usage();
	    exit(1);
	} else {
	    usage();
	    exit(0);
	}
    }

    msg("---------------- ransack ----------------\n");

    /* advise data format */
    advise_fmt(&fmt);

    /* tolerance angle for multiple intersections */
    if (mtol != 0.) {
	scale(&mtol, munit, 's');
	munit = 's';
	msg("multiple intersections closer than %Lg%c will be treated as coincident\n", mtol, munit);
	scale(&mtol, munit, 'r');
	munit = 'r';
    }

    /* warn about seed not being set */
    if (seed_read == 0) {
	msg("warning: seed was not set on command line: using default seed %d\n", seed);
    }

    /* read polygons */
    npoly = 0;
    nfiles = argc - 1 - optind;
    for (ifile = optind; ifile < optind + nfiles; ifile++) {
        npolys = rdmask(argv[ifile], &fmt, NPOLYSMAX - npoly, &poly[npoly], 1);
	if (npolys == -1) exit(1);
	npoly += npolys;
    }
    if (nfiles >= 2) {
	msg("total of %d polygons read\n", npoly);
    }
    if (npoly == 0) {
	msg("STOP\n");
	exit(0);
    }
 
   if (snapped==0 || balkanized==0) {
     msg("WARNING: 'snapped' and 'balkanized' keywords not found in all input files.\n");
     msg("Running ransack on polygons that are not snapped and balkanized may give misleading results.\n");
   }

    /* random points in polygons */
    ifile = argc - 1;
    np = ransack(argv[ifile], &fmt, npoly, NPOLYSMAX, poly);
    if (np == -1) exit(1);
 
    for(i=0;i<npoly;i++){
      free_poly(poly[i]);
    }

    return(0);
}
Esempio n. 2
0
/*------------------------------------------------------------------------------
  Generate random az, el positions within mask defined by poly.
  The results are written to out_filename.

   Input: out_filename = name of file to write to;
			"" or "-" means write to standard output.
	  fmt = pointer to format structure.
	  npoly = number of polygons in poly array.
	  npolysmax = maximum number of polygons in poly array.
	  poly = array of pointers to polygons.
	  mtol = initial tolerance angle for multiple intersections.
  Return value: number of random points generated,
		or -1 if error occurred.
*/
int ransack(char *out_filename, format *fmt, int npoly, int npolysmax, polygon *poly[/*npolysmax*/])
{
/* number of extra caps to allocate to polygon, to allow for expansion */
#define DNP			4
/* length of state vector for random number generator */
#define STATELEN		256
    static char state[STATELEN], stateo[STATELEN];
#define AZEL_STR_LEN		32
    char output[] = "output";
    char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN];
    int dnp, dnwl, i, idwidth, ier, in, inull, ip, ipmin, ipoly, iprune, irandom, lassoed, np, nwl, tries, verb, width, k;
    long long idmin,idmax;
    int *dlasso=0x0, *lasso=0x0;
    long double area, cmmin, cmi, phi, rpoly, si, tol, w, wcum, x, y, z;
    long double *wpoly;
    vec rp, xi, yi;
    azel v;
    char *out_fn;
    FILE *outfile;

    /* open out_filename for writing */
    if (!out_filename || strcmp(out_filename, "-") == 0) {
	outfile = stdout;
	out_fn = output;
    } else {
	outfile = fopen(out_filename, "w");
	if (!outfile) {
	    fprintf(stderr, "ransack: cannot open %s for writing\n", out_filename);
	    goto error;
	}
	out_fn = out_filename;
    }

    /* advise angular units */
    if (fmt->outunit != fmt->inunit) {
	msg("units of output az, el angles will be ");
	switch (fmt->outunit) {
#include "angunit.h"
	}
	msg("\n");
    }

    /* initialize random number generator used by ransack() */
    initstate(seed, state, STATELEN);
    /* initialize random number generator used by ikrand() */
    initstate(seed, stateo, STATELEN);

    /* prune polygons, discarding those with zero weight * area */
    msg("pruning %d polygons ...\n", npoly);
    ier = 0;
    inull = 0;
    np = 0;
    for (ipoly = 0; ipoly < npoly; ipoly++) {
	/* zero weight polygon */
	if (poly[ipoly]->weight == 0.) {
            inull++;
	    free_poly(poly[ipoly]);
	    poly[ipoly] = 0x0;
	} else {
	/* prune polygon */
	    iprune = prune_poly(poly[ipoly], mtol);
	    /* error */
	    if (iprune == -1) {
		ier++;
		free_poly(poly[ipoly]);
		poly[ipoly] = 0x0;
		fprintf(stderr, "ransack: failed to prune polygon %d; discard it\n", ipoly);
		/* goto error; */
	    /* zero area polygon */
	    } else if (iprune >= 2) {
		inull++;
		free_poly(poly[ipoly]);
		poly[ipoly] = 0x0;
	    } else {
		np++;
	    }
	}
    }
   /*copy down non-null polygons*/
    k=0;
    for(ipoly = 0; ipoly < npoly; ipoly++){
      if(poly[ipoly]){
	poly[k++]=poly[ipoly];
      }
    }
    /*after copying non-null polygons, k should be equal to np */
    if(k!=np){
      fprintf(stderr, "ransack: should be left with %d non-null polygons, but actually have %d\n",np,k);
    }

    /*nullify the rest of the array, but don't free, since pointers have been copied above*/
    for(ipoly=np; ipoly < npoly; ipoly++){
      poly[ipoly]=0x0;
    }

    if (ier > 0) {
	msg("discarding %d unprunable polygons\n", ier);
    }
    if (inull > 0) {
	msg("discarding %d polygons with zero weight * area\n", inull);
    }
    /* number of polygons with finite weight * area */
    npoly = np;

    /* no polygons */
    if (npoly == 0) {
	fprintf(stderr, "ransack: no polygons to generate random points inside!\n");
	goto error;
    }

    /* pre-lasso polygons if there are many random points */
    if (nrandom >= npoly) {
	msg("lassoing %d polygons ...\n", npoly);

	/* lasso each polygon */
	np = npoly;
	for (ipoly = 0; ipoly < npoly; ipoly++) {
	    ier = lasso_poly(&poly[ipoly], npolysmax - np, &poly[np], mtol, &dnp);
	    if (ier == -1) {
		fprintf(stderr, "ransack: UHOH at polygon %lld; continuing ...\n", poly[ipoly]->id);
	    }

	    /* lassoed polygons are an improvement over original polygon */
	    if (dnp > 0) {
		/* check whether exceeded maximum number of polygons */
		if (np + dnp > npolysmax) {
		    fprintf(stderr, "ransack: total number of polygons exceeded maximum %d\n", npolysmax);
		    fprintf(stderr, "if you need more space, enlarge NPOLYSMAX in defines.h, and recompile\n");
		    goto error;
		}

		/* decrement dnp by 1 */
		dnp--;

		/* increment number of polygons */
		np += dnp;

		/* move last polygon part into poly[ipoly] */
		free_poly(poly[ipoly]);
		poly[ipoly] = poly[np];
		poly[np] = 0x0;
	    }
	}

	/* revised number of polygons */
	npoly = np;

	/* flag that all polygons have been lassoed */
	lassoed = 1;

    /* two few random points to make it worth pre-lassoing */
    } else {
	/* flag that all polygons have not been lassoed */
	lassoed = 0;

    }

    /* allocate memory for wpoly array */
    nwl = npoly;
    wpoly = (long double *) malloc(sizeof(long double) * nwl);
    if (!wpoly) {
        fprintf(stderr, "ransack: failed to allocate memory for %d long doubles\n", nwl);
        goto error;
    }
    if (!lassoed) {
	/* allocate memory for lasso and dlasso arrays */
	lasso = (int *) malloc(sizeof(int) * nwl);
	if (!lasso) {
	    fprintf(stderr, "ransack: failed to allocate memory for %d ints\n", nwl);
	    goto error;
	}
	dlasso = (int *) malloc(sizeof(int) * nwl);
	if (!dlasso) {
	    fprintf(stderr, "ransack: failed to allocate memory for %d ints\n", nwl);
	    goto error;
	}

	/* initialize dlasso array to zero */
	for (ipoly = 0; ipoly < nwl; ipoly++) dlasso[ipoly] = 0;
    }

    /* largest width of polygon id number */
    idmin = 0;
    idmax = 0;
    for (ipoly = 0; ipoly < npoly; ipoly++) {
	if (poly[ipoly]->id < idmin) idmin = poly[ipoly]->id;
	if (poly[ipoly]->id > idmax) idmax = poly[ipoly]->id;
    }
    idmin = ((idmin < 0)? floorl(log10l((long double)-idmin)) + 2 : 1);
    idmax = ((idmax > 0)? floorl(log10l((long double)idmax)) + 1 : 1);
    idwidth = ((idmin > idmax)? idmin : idmax);

    /* write header */
    wrangle(0., fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str);
    width = strlen(az_str);
    if (fmt->outunit == 'h') {
	sprintf(az_str, "az(hms)");
	sprintf(el_str, "el(dms)");
    } else {
	sprintf(az_str, "az(%c)", fmt->outunit);
	sprintf(el_str, "el(%c)", fmt->outunit);
    }
    fprintf(outfile, "%*s\t%*s\t%*s\n", width, az_str, width, el_str, idwidth, "id");

    /* accept error messages from garea */
    /* unprunable polygons were already discarded, so garea should give no errors */
    verb = 1;

    /* cumulative area times weight of polygons */
    w = 0.;
    for (ipoly = 0; ipoly < npoly; ipoly++) {
	/* skip null polygons */
	if (poly[ipoly]) {
	    /* area of polygon */
	    tol = mtol;
	    ier = garea(poly[ipoly], &tol, verb, &area);
	    if (ier) goto error;
	    /* accumulate weight times area */
	    w += poly[ipoly]->weight * area;
	}
	wpoly[ipoly] = w;
    }
    wcum = w;

    /* random points */
    if (strcmp(out_fn, output) != 0) {
	msg("generating %d random points from seed %u in %d polygons ...\n", nrandom, seed, npoly);
    }
    for (irandom = 0; irandom < nrandom; irandom++) {

	/* random number in interval [0, 1) wcum */
	setstate(state);
	rpoly = drandom() * wcum;
	setstate(stateo);

	/* which polygon to put random point in */
	ipoly = search(npoly, wpoly, rpoly);

	/* guard against roundoff */
	if (ipoly >= npoly) {
	    fprintf(stderr, "ransack: %d should be < %d (i.e. %.15Lg < %.15Lg)\n", ipoly, npoly, rpoly, wpoly[npoly - 1]);
	    ipoly = npoly - 1;
	}

	/* all polygons have not been lassoed */
	if (!lassoed) {

	    /* polygon has not yet been lassoed */
	    if  (dlasso[ipoly] == 0) {

		/* lasso polygon */
		ier = lasso_poly(&poly[ipoly], npolysmax - np, &poly[np], mtol, &dnp);
		if (ier == -1) {
		    fprintf(stderr, "ransack: UHOH at polygon %lld; continuing ...\n", poly[ipoly]->id);
		}

		/* go with original polygon */
		if (dnp == 0) {
		    /* lasso, dlasso */
		    lasso[ipoly] = ipoly;
		    dlasso[ipoly] = 1;

		/* lassoed polygons are an improvement over original */
		} else {
		    /* check whether exceeded maximum number of polygons */
		    if (np + dnp > npolysmax) {
			fprintf(stderr, "ransack: total number of polygons exceeded maximum %d\n", npolysmax);
			fprintf(stderr, "if you need more space, enlarge NPOLYSMAX in defines.h, and recompile\n");
			goto error;
		    }

		    /* just one lassoed polygon */
		    if (dnp == 1) {
			/* move last polygon part into poly[ipoly] */
			free_poly(poly[ipoly]);
			poly[ipoly] = poly[np];
			poly[np] = 0x0;

			/* lasso, dlasso */
			lasso[ipoly] = ipoly;
			dlasso[ipoly] = 1;

		    /* more than one lassoed polygon */
		    } else {
			/* enlarge memory for wpoly, lasso, and dlasso arrays */
			if (np + dnp > nwl) {
			    dnwl = dnp + 1024;
			    wpoly = (long double *) realloc(wpoly, sizeof(long double) * (nwl + dnwl));
			    if (!wpoly) {
				fprintf(stderr, "ransack: failed to reallocate memory for %d long doubles\n", nwl + dnwl);
				goto error;
			    }
			    lasso = (int *) realloc(lasso, sizeof(int) * (nwl + dnwl));
			    if (!lasso) {
				fprintf(stderr, "ransack: failed to reallocate memory for %d ints\n", nwl + dnwl);
				goto error;
			    }
			    dlasso = (int *) realloc(dlasso, sizeof(int) * (nwl + dnwl));
			    if (!dlasso) {
				fprintf(stderr, "ransack: failed to reallocate memory for %d ints\n", nwl + dnwl);
				goto error;
			    }

			    /* initialize new part of lasso and dlasso arrays to inconsistent values */
			    for (ipoly = nwl; ipoly < nwl + dnwl; ipoly++) lasso[ipoly] = 1;
			    for (ipoly = nwl; ipoly < nwl + dnwl; ipoly++) dlasso[ipoly] = 0;

			    /* revised size of wpoly, lasso, and dlasso arrays */
			    nwl += dnwl;
			}

			/* lasso, dlasso */
			lasso[ipoly] = np;
			dlasso[ipoly] = dnp;

			/* cumulative weight times area of lassoed polygons */
			w = (ipoly == 0)? 0. : wpoly[ipoly-1];
			for (ip = np; ip < np + dnp; ip++) {
			    /* area of polygon */
			    tol = mtol;
			    ier = garea(poly[ip], &tol, verb, &area);
			    if (ier) goto error;
			    /* accumulate area times weight */
			    w += poly[ip]->weight * area;
			    wpoly[ip] = w;
			}

			/* increment number of polygons */
			np += dnp;
		    }

		}

	    }

	    /* polygon was partitioned into at least two */
	    if (dlasso[ipoly] >= 2) {
		/* which polygon to put random point in */
		ip = search(dlasso[ipoly], &wpoly[lasso[ipoly]], rpoly);

		/* guard against roundoff */
		if (ip >= lasso[ipoly] + dlasso[ipoly]) {
		    fprintf(stderr, "ransack: %d should be < %d (i.e. %.15Lg < %.15Lg)\n", ip, lasso[ipoly] + dlasso[ipoly], rpoly, wpoly[lasso[ipoly] + dlasso[ipoly] - 1]);
		    ip = lasso[ipoly] + dlasso[ipoly] - 1;
		}

		/* revised polygon number to put random point in */
		ipoly = ip;
	    }
	}

	/* smallest cap of polygon */
	cmminf(poly[ipoly], &ipmin, &cmmin);

	/* random point within polygon */
	tries = 0;
	do {
	    tries++;
	    /* random point within smallest cap */
	    setstate(state);
	    phi = TWOPI * drandom();
	    cmi = cmmin * drandom();
	    setstate(stateo);
	    /* coordinates of random point in cap frame */
	    si=sqrtl(cmi * (2. - cmi));
	    x = si * cosl(phi);
	    y = si * sinl(phi);
	    z = 1. - cmi;
	    /* polygon has caps */
	    if (poly[ipoly]->np > 0) {
		if (poly[ipoly]->cm[ipmin] < 0.) z = -z;
		/* Cartesian axes with z-axis along cap axis */
		gaxisi_(poly[ipoly]->rp[ipmin], xi, yi);
		/* coordinates of random point */
		for (i = 0; i < 3; i++) rp[i] = x * xi[i] + y * yi[i] + z * poly[ipoly]->rp[ipmin][i];
		/* whether random point is inside polygon */
		in = gptin(poly[ipoly], rp);
	    /* polygon has no caps, so is the whole sphere */
	    } else {
		rp[0] = x;
		rp[1] = y;
		rp[2] = z;
		in = 1;
	    }
	} while (!in);

	/* convert unit vector to az, el */
	rp_to_azel(rp, &v);
	v.az -= floorl(v.az / TWOPI) * TWOPI;

	/* convert az and el from radians to output units */
	scale_azel(&v, 'r', fmt->outunit);

	/* write result */
	wrangle(v.az, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str);
	wrangle(v.el, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, el_str);
	fprintf(outfile, "%s\t%s\t%*lld\n", az_str, el_str, idwidth, poly[ipoly]->id);
	/* fprintf(outfile, "%s %s %d %d %d %Lg %Lg %Lg %Lg %d %d\n", az_str, el_str, irandom, ipoly, tries, wcum, rpoly / wcum, area, TWOPI * cmmin / area, ipmin, poly[ipoly]->np); */

    }

    /* advise */
    if (outfile != stdout) {
	msg("ransack: %d random positions written to %s\n", nrandom, out_fn);
    }

    return(nrandom);

    /* error returns */
    error:
    return(-1);
}
Esempio n. 3
0
/*------------------------------------------------------------------------------
  Main program.
*/
int main(int argc, char *argv[])
{
    int ifile, nfiles, npoly, npolys,i;
    polygon **polys;
    polys=polys_global;

    /* default output format */
    fmt.out = keywords[POLYGON];
    /* default is to renumber output polygons with old id numbers */
    fmt.newid = 'o';

    /* parse arguments */
    parse_args(argc, argv);

    /* tolerance angle for multiple intersections */
    if (mtol != 0.) {
	scale(&mtol, munit, 's');
	munit = 's';
	msg("multiple intersections closer than %Lg%c will be treated as coincident\n", mtol, munit);
	scale(&mtol, munit, 'r');
	munit = 'r';
    }

    /* at least one input and output filename required as arguments */
    if (argc - optind < 2) {
	if (optind > 1 || argc - optind == 1) {
	    fprintf(stderr, "%s requires at least 2 arguments: polygon_infile and polygon_outfile\n", argv[0]);
	    usage();
	    exit(1);
	} else {
	    usage();
	    exit(0);
	}
    }

    msg("---------------- grow ----------------\n");

    /*process grow angle */
    scale(&grow_angle, gunit, 's');
    gunit = 's';
    msg("Borders of %Lg%c will be grown around the input polygons.\n", grow_angle, gunit);
    scale(&grow_angle, gunit, 'r');
    gunit = 'r';
    
    /* check if input polygons are pixelized - for this routine we need them to *NOT* be pixelized */
    if (pixelized==1) {
      fprintf(stderr, "Error: input polygons are pixelized. The grow function can only be applied to non-pixelized polygons.");
      exit(1);
    }

    /* advise data format */
    advise_fmt(&fmt);

    /* read polygons */
    npoly = 0;
    nfiles = argc - 1 - optind;
    for (ifile = optind; ifile < optind + nfiles; ifile++) {
        npolys = rdmask(argv[ifile], &fmt, NPOLYSMAX - npoly, &polys[npoly], 1);
	if (npolys == -1) exit(1);
	npoly += npolys;
    }
    if (nfiles >= 2) {
        msg("total of %d polygons read\n", npoly);
    }
    if (npoly == 0) {
	msg("STOP\n");
	exit(0);
    }

    /* grow polygons */
    npolys=grow(npoly, polys, NPOLYSMAX-npoly, &polys[npoly], grow_angle);
    if (npolys == -1) exit(1);

    ifile = argc - 1;
    npolys = wrmask(argv[ifile], &fmt, npolys, polys);
    if (npolys == -1) exit(1);
 
    for(i=0;i<npolys;i++){
      free_poly(polys[i]);
    }

    return(0);
}
Esempio n. 4
0
File: test.c Progetto: MCTwo/DEIMOS
int main(int argc, char *argv[])
{
  int ifile, ipoly, nfiles, npoly;
   
  int i, pixel, res, n, m, pixel_num;
  double ra, dec;
  char scheme;
  int *child_pix;
  int children;
  int *parent_pix;
   polygon **polys;
   polys=polys_global;

  /* default output format */
  fmt.out = keywords[POLYGON];
  
  
  /*    
  if(argc<5){
    msg("enter the arguments for which_pixel as command line arguments:\n ra, dec, resolution, and pixelization scheme.\n");
    exit(1);
  } 
  else{
    ra=atof(argv[1]);
    dec=atof(argv[2]);
    res=atoi(argv[3]);
    scheme=argv[4][0];
    
    scale(&ra, 'd', 'r');
    scale(&dec, 'd','r');
    
    pixel = which_pixel(ra,dec,res,scheme);
    printf("pixel=%i\n",pixel);  
    return(0);
  }
  */
  
  
  /*  
  if(argc<3){
    msg("enter the arguments for get_child_pixels as command line arguments:\n pixel number and pixelization scheme.\n");
    exit(1);
  }
  else{
    pixel_num=atoi(argv[1]);
    scheme=argv[2][0];

    //allocate memory for child_pix array
    if(scheme=='d' && pixel_num==0){
      child_pix=(int *) malloc(sizeof(int) * 117);
      children=117;
      if(!child_pix){
	fprintf(stderr, "get_child_pixels: failed to allocate memory for %d integers\n", 117);
	return(-1);
      }
    }
    else{
      child_pix=(int *) malloc(sizeof(int) * 4);
      children=4;
      if(!child_pix){
	fprintf(stderr, "get_child_pixels: failed to allocate memory for %d integers\n", 4);
	return(-1);
      }
    }

    get_child_pixels(pixel_num,child_pix,scheme);
    printf("parent pixel = %d\n", pixel_num);

    for(i=0;i<children;i++){
      printf("child pixel %d = %d\n", i+1, child_pix[i]);
    }
    return(0);
  }
  */  

  /*
    if(argc<3){
      msg("enter the arguments for get_parent_pixels as command line arguments:\n pixel number and pixelization scheme.\n");
      exit(1);
    }
    else{
      pixel_num=atoi(argv[1]);
      scheme=argv[2][0];
      res=get_res(pixel_num, scheme);
      printf("res=%d\n",res);
      
      if(pixel_num==0 && scheme=='d'){
        parent_pix = (int *) malloc(sizeof(int) * (168));
	if (!parent_pix){
	  fprintf(stderr, "test: failed to allocate memory for 168 integers\n");
	  exit(1);
        }
      }
      else{
        parent_pix = (int *) malloc(sizeof(int) * (res+1));
        if (!parent_pix) {
	  fprintf(stderr, "test: failed to allocate memory for %d integers\n", res);
	  exit(1);
        }
      }
      get_parent_pixels(pixel_num,parent_pix,scheme);
      printf("child pixel = %d\nparent pixels =", pixel_num);
      for(i=0;i<res;i++){
	printf(" %d, ",parent_pix[i]);
      }
      printf("and %d\n",parent_pix[res]);
      free(parent_pix);
      return(0);
    }
  
  */

  
   
   if(argc<4){
    msg("enter as command line arguments:\n resolution, pixelization scheme, and name of output file\n");
    return(1);
  }
  else{
    res=atoi(argv[1]);
    scheme=argv[2][0];
    
    if(scheme=='s'){
      npoly=pow(4,res);
    }

    if(scheme=='d'){
      if(res==0) npoly=1;
      else if(res==1) npoly=117;
      else{
	npoly=468*pow(4,res-2);
      }
    }

    npoly=1;
    polys[0]=get_pixel(400, scheme);

    /*
    for(ipoly=0;ipoly<npoly;ipoly++){
      //pixel_num=ipoly+(int)((pow(4,res)+1)/3);
      pixel_num=ipoly+pixel_start(res, scheme);
      polys[ipoly]=get_pixel(pixel_num,scheme);
      
      m=ipoly % (int)(pow(2,res));
      n=(ipoly-m)/pow(2,res);
      
      // polys[ipoly]->weight=(n+m) % 2;
      polys[ipoly]->id=ipoly;
      polys[ipoly]->weight=(double)ipoly/(double)npoly;
    }
    */
    
    ifile = argc - 1;
    
    advise_fmt(&fmt);
    
    npoly = wrmask(argv[ifile], &fmt, npoly, polys);
    
    if (npoly == -1) exit(1);

    for(ipoly=0;ipoly<npoly;ipoly++){
    free_poly(polys[ipoly]);
    }

      
      return(0);
  }
   
    

}
Esempio n. 5
0
void free_bsp_node(bsp_node_t *node) {
	if(node == NULL) return;
	kl_destroy(poly, node->polygons);
	free_poly(node->divider, 1);
	free(node);
}
Esempio n. 6
0
/*------------------------------------------------------------------------------
  Fragment poly1 into several disjoint polygons,
  each of which is either wholly outside or wholly inside poly2.

   Input: *poly1, poly2 are 2 polygons.
	  discard = 0 to retains all parts of poly1;
	  	  = 1 to discard intersection of poly1 with poly2.
	  npolys = maximum number of polygons available in polys array.
	  mtol = initial angular tolerance within which to merge multiple intersections.
  Output: *poly1 and polys[i], i = 0 to npoly - 1,
		are disjoint polygons of poly1;
		all but the last polygon lie outside poly2;
		if discard = 0:
		    if poly1 intersects poly2, then the last polygon,
		    polys[npoly - 1] (or *poly1 if npoly = 0),
		    is the intersection of poly1 and poly2;
		if discard = 1:
		    if poly1 intersects poly2, then the last+1 polygon,
		    polys[npoly],
		    is the discarded intersection of poly1 and poly2;
		    if poly1 lies entirely inside poly2 (so npoly = 0),
		    then *poly1 is set to null.
  Return value: npoly = number of disjoint polygons, excluding poly1,
			or -1 if error occurred in split_poly().
*/
int fragment_poly(polygon **poly1, polygon *poly2, int discard, int npolys, polygon *polys[/*npolys*/], long double mtol, char bmethod)
{
    int npoly, nsplit;
    polygon **poly;

    /* iteratively subdivide polygons of poly1 */
    npoly = 0;
    poly = poly1;
    while (1) {
	/* check space is available */
	if (npoly >= npolys) return(npoly + 1);
	/* split */
	nsplit = split_poly(poly, poly2, &polys[npoly], mtol);
	/* error */
	if (nsplit == -1) return(-1);
	/* done */
	if (nsplit == 0 || nsplit == 1) {
	    if (nsplit == 1 && discard) {
		if (npoly == 0) {
		    free_poly(*poly);
		    *poly = 0x0;
		} else {
		    npoly--;
		}
	    }
	    if(discard==0 && nsplit==1){
	      if(npoly>0){
		/* set weight according to balkanization scheme: */
		if(bmethod=='l'){
		  //do nothing - this is the default behavior
		}
		else if(bmethod=='a'){
		  polys[npoly-1]->weight=(*poly1)->weight + poly2->weight;
		}
		else if(bmethod=='n'){
		  polys[npoly-1]->weight=((*poly1)->weight > poly2->weight)? poly2->weight : (*poly1)->weight ;
		}
		else if(bmethod=='x'){
		  polys[npoly-1]->weight=((*poly1)->weight > poly2->weight)? (*poly1)->weight : poly2->weight ;
		}
		else{
		  fprintf(stderr, "error in fragment_poly: balkanize method %c not recognized.\n", bmethod);
		  return(-1);
		}
	      }
	      else{
		/* set weight according to balkanization scheme: */
		if(bmethod=='l'){
		  //do nothing - this is the default behavior
		}
		else if(bmethod=='a'){
		  (*poly1)->weight=(*poly1)->weight + poly2->weight;
		}
		else if(bmethod=='n'){
		  (*poly1)->weight=((*poly1)->weight > poly2->weight)? poly2->weight : (*poly1)->weight ;
		}
		else if(bmethod=='x'){
		  (*poly1)->weight=((*poly1)->weight > poly2->weight)? (*poly1)->weight : poly2->weight ;
		}
		else{
		  fprintf(stderr, "error in fragment_poly: balkanize method %c not recognized.\n", bmethod);
		  return(-1);
		}
	      }
	    }
	    return(npoly);
	}
	poly = &polys[npoly++];
    }

}