Ejemplo n.º 1
0
/*------------------------------------------------------------------------------
  Write mask data in circle format.

  Input: filename = name of file to write to;
  "" or "-" means write to standard output.
  fmt = pointer to format structure.
  polys = polygons to write.
  npolys = number of polygons.
  npolyw = number of polygons to write.
  Return value: number of polygons written,
  or -1 if error occurred.
*/
int wr_circ(char *filename, format *fmt, int npolys, polygon *polys[/*npolys*/], int npolyw)
{
  char unit;
  char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN], th_str[AZEL_STR_LEN];
  int i, ier, ip, ipoly, nbadarea, npoly;
  double area, angle[3], tol;
  FILE *file;
  char *circle_fmt = "circle %d ( %d caps, %.15lg weight, %.15lf str):\n";

  /* open filename for writing */
  if (!filename || strcmp(filename, "-") == 0) {
    file = stdout;
  } else {
    file = fopen(filename, "w");
    if (!file) {
      fprintf(stderr, "wr_circ: cannot open %s for writing\n", filename);
      return(-1);
    }
  }

  /* write number of polygons */
  fprintf(file, "%d polygons\n", npolyw);

  /* write angular unit */
  fprintf(file, "unit %c\n", fmt->outunitp);

  npoly = 0;
  nbadarea = 0;
  for (ipoly = 0; ipoly < npolys; ipoly++) {
    /* discard null polygons */
    if (!polys[ipoly]) continue;
    /* area of polygon */
    tol = mtol;
    ier = garea(polys[ipoly], &tol, verb, &area);
    if (ier == -1) return(-1);
    if (ier) {
      fprintf(stderr, "wr_circ: area of polygon %d is incorrect\n", polys[ipoly]->id);
      nbadarea++;
    }
    /* number of caps, weight, and area of polygon */
    fprintf(file, circle_fmt,
            polys[ipoly]->id, polys[ipoly]->np, polys[ipoly]->weight, area);
    /* write boundaries of polygon */
    for (ip = 0; ip < polys[ipoly]->np; ip++) {
      rpcm_to_circ(polys[ipoly]->rp[ip], &polys[ipoly]->cm[ip], angle);
      switch (fmt->outphase) {
      case '+':	if (angle[0] < 0.) angle[0] += TWOPI;	break;
      case '-':	if (angle[0] > PI) angle[0] -= TWOPI;	break;
      }
      for (i = 0; i < 3; i++) {
        unit = fmt->outunitp;
        if (i > 0 && fmt->outunitp == 'h') unit = 'd';
        scale(&angle[i], 'r', unit);
      }
      wrangle(angle[0], fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, az_str);
      wrangle(angle[1], fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, el_str);
      wrangle(angle[2], (fmt->outunitp == 'h')? 'd' : fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, th_str);
      fprintf(file, " %s %s %s", az_str, el_str, th_str);
    }
    fprintf(file, "\n");
    /* increment polygon count */
    npoly++;
  }

  /* warn about polygons with incorrect area */
  if (nbadarea > 0) {
    msg("%d polygons have incorrect area, but kept\n", nbadarea);
  }

  /* advise */
  msg("%d polygons written to %s\n",
      npoly, (file == stdout)? "output": filename);

  /* close file */
  if (file != stdout) fclose(file);

  return(npoly);
}
Ejemplo n.º 2
0
/*------------------------------------------------------------------------------
  Discard polygons with weight or area outside specified limits.

  Input: polys = polygons.
  npolys = number of polygons.
  Return value: number of polygons retained,
  or -1 if error occurred.
*/
int discard_poly(int npolys, polygon *polys[/*npolys*/])
{
  int discard, ier, ipoly, nbadarea, noutarea, noutweight, npoly;
  double area, tol;

  if (is_weight_min || is_weight_max || is_area_min || is_area_max) {
    noutweight = 0;
    nbadarea = 0;
    noutarea = 0;
    for (ipoly = 0; ipoly < npolys; ipoly++) {
	    discard = 0;

	    /* discard polygons with weights outside interval */
	    if (is_weight_min && is_weight_max) {
        /* min <= max */
        if (weight_min <= weight_max) {
          if (polys[ipoly]->weight < weight_min
              || polys[ipoly]->weight > weight_max) {
            discard = 1;
          }
          /* min > max */
        } else {
          if (polys[ipoly]->weight < weight_min
              && polys[ipoly]->weight > weight_max) {
            discard = 1;
          }
        }
	    } else if (is_weight_min) {
        if (polys[ipoly]->weight < weight_min) {
          discard = 1;
        }
	    } else if (is_weight_max) {
        if (polys[ipoly]->weight > weight_max) {
          discard = 1;
        }
	    }
	    if (discard) {
        noutweight++;
        free_poly(polys[ipoly]);
        polys[ipoly] = 0x0;
        continue;
	    }

	    /* area of polygon */
	    tol = mtol;
	    ier = garea(polys[ipoly], &tol, verb, &area);
	    if (ier == -1) return(-1);
	    if (ier) {
        nbadarea++;

        /* discard polygons with areas outside interval */
	    } else if (is_area_min && is_area_max) {
        /* min <= max */
        if (area_min <= area_max) {
          if (area < area_min
              || area > area_max) {
            discard = 1;
          }
          /* min > max */
        } else {
          if (area < area_min
              && area > area_max) {
            discard = 1;
          }
        }
	    } else if (is_area_min) {
        if (area < area_min) {
          discard = 1;
        }
	    } else if (is_area_max) {
        if (area > area_max) {
          discard = 1;
        }
	    }
	    if (discard) {
        noutarea++;
        free_poly(polys[ipoly]);
        polys[ipoly] = 0x0;
        continue;
	    }

    }

    /* warn about discarded polygons */
    if (noutweight > 0) {
	    if (is_weight_min && is_weight_max) {
        if (weight_min < weight_max) {
          msg("%d polygons with weights outside [%g, %g] discarded\n",
              noutweight, weight_min, weight_max);
        } else {
          msg("%d polygons with weights inside (%g, %g) discarded\n",
              noutweight, weight_max, weight_min);
        }
	    } else if (is_weight_min) {
        msg("%d polygons with weights < %g discarded\n",
            noutweight, weight_min);
	    } else if (is_weight_max) {
        msg("%d polygons with weights > %g discarded\n",
            noutweight, weight_max);
	    }
    }
    if (noutarea > 0) {
	    if (is_area_min && is_area_max) {
        if (area_min < area_max) {
          msg("%d polygons with areas outside [%g, %g] discarded\n",
              noutarea, area_min, area_max);
        } else {
          msg("%d polygons with areas inside (%g, %g) discarded\n",
              noutarea, area_max, area_min);
        }
	    } else if (is_area_min) {
        msg("%d polygons with areas < %g discarded\n",
            noutarea, area_min);
	    } else if (is_area_max) {
        msg("%d polygons with areas > %g discarded\n",
            noutarea, area_max);
	    }
    }

  }

  /* count non-null polygons */
  npoly = 0;
  for (ipoly = 0; ipoly < npolys; ipoly++) {
    if (polys[ipoly]) npoly++;
  }

  return(npoly);
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
0
/*------------------------------------------------------------------------------
  Take pixelized polygons, find the average weight within each pixel, and return a set of polygons consisting of the pixels weighted with the average weight.

   Input: poly = array of pointers to polygons.
	  npoly = pointer to number of polygons.
  Output: polys = array of pointers to polygons;
  Return value: number of polygons discarded by pixelmapping,
		or -1 if error occurred.
*/
int pixelmap(int *npoly, polygon *poly[/**npoly*/])
{
  int i, j, nadj, k, kstart,kend,numpix;
  int *start;
  int *total;
  int *parent_pixels;
  int begin, end, p,max_pixel,min_pixel, ier, verb,res1,res2;
  long double tol,area, tot_area;
  long double *av_weight;
  long double *av_weight0;

  poly_sort(*npoly,poly,'p');
  min_pixel = poly[0]->pixel; 
  max_pixel = poly[*npoly-1]->pixel+1; 
  res1=get_res(min_pixel,scheme);
  res2=get_res(max_pixel,scheme);

  if(res1<res_max){
    fprintf(stderr,"pixelmap: there are pixels in the mask with a lower resolution than the desired pixelmap resolution %d.  The desired pixelmap resolution can be set with the -P option.\n",res_max);
    fprintf(stderr,"Before using pixelmap, use pixelize with the -P0,r option to pixelize the entire mask to the desired resolution r.\n");
    return(-1);
  }

 
  /* allocate memory for pixel info arrays start and total */ 
  start = (int *) malloc(sizeof(int) * max_pixel);
  if (!start) {
    fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", max_pixel);
    return(-1);
  }
  total = (int *) malloc(sizeof(int) * max_pixel);
  if (!total) {
    fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", max_pixel);
    return(-1);
  }

  /* build lists of starting indices of each pixel and total number of polygons in each pixel*/
  ier=pixel_list(*npoly, poly, max_pixel, start, total);
  if (ier == -1) {
    fprintf(stderr, "pixelmap: error building pixel index lists\n");
    return(-1);
  } 

  //allocate memory for parent pixels array
  parent_pixels = (int *) malloc(sizeof(int) * (res2+1));
  if (!parent_pixels) {
    fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", res2+1);
    return(-1);
  }

  //kstart=number of first pixel at desired output resolution
  //kend=number of last pixel at desired output resolution
  if(res_max==-1){
    kstart=pixel_start(res1,scheme);
    kend=pixel_start(res2+1,scheme)-1;
  }
  else{
    kstart=pixel_start(res_max,scheme);
    kend=pixel_start(res_max+1,scheme)-1;
  }
  av_weight0= (long double *) malloc(sizeof(long double) * (kend-kstart+1) );
  if (!av_weight0) {
    fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", kend-kstart+1 );
    return(-1);
  }
  //make av_weight an array indexed by the pixel number 
  av_weight=av_weight0-kstart;

  //set av_weight array to 0 initially
  for(k=kstart;k<=kend;k++){
    av_weight[k]=0;
  }

  nadj = 0;
  verb=1;
   
  /*find average weight of polygons within each pixel*/
  for(p=min_pixel;p<max_pixel;p++){
    begin=start[p];
    end=start[p]+total[p];
    ier=get_parent_pixels(p,parent_pixels,scheme);
    if(ier) return(-1);
    
    //set k to the pixel at the desired output resolution, or to the pixel number if using
    //existing resolution

    k=(res_max==-1) ? p : parent_pixels[res_max];
    
    for (i = begin; i < end; i++) {
      if (!poly[i]) continue;
      tol=mtol;
      ier = garea(poly[i], &tol, verb, &area);
      if(ier==1 || ier == -1){
	fprintf(stderr, "error %d in garea in polygon %d\n", ier, poly[i]->id);
	continue;
      }
      
      av_weight[k]+=poly[i]->weight * area;
    }
  }
  
  //replace polygons in input array with non-zero weight pixels
  j=0;
  for(k=kstart;k<=kend;k++){
    if(av_weight[k]==0) continue;
    free_poly(poly[j]);
    poly[j]=get_pixel(k,scheme);
    tol=mtol;
    ier = garea(poly[j], &tol, verb, &tot_area);
    if(ier==1 || ier == -1){
      fprintf(stderr, "pixelmap: error in garea in pixel %d\n",p);
      continue;
    }
    poly[j]->weight=av_weight[k]/tot_area;
    j++;
    if(j> *npoly ){
      fprintf(stderr,"pixelmap: number of pixels with non-zero weight exceeds number of polygons.\n");
      fprintf(stderr, "Try running unify on your mask to remove zero-weight polygons before using pixelmap.\n");
    }
  }

  numpix=j;
  
  for(j=numpix; j< *npoly; j++){
    free_poly(poly[j]);
    poly[j] = 0x0;
    nadj++;
  }

  *npoly=numpix;

  free(start);
  free(total);
  free(parent_pixels);
  free(av_weight0);
  
  /* assign new polygon id numbers */
  if (fmt.newid == 'n') {
    for (i = 0; i < *npoly; i++) {
      poly[i]->id = i;
    }
  }
  
  if (fmt.newid == 'p') {
    for (i = 0; i < *npoly; i++) {
      poly[i]->id = poly[i]->pixel;
    }
  }
  
  /* advise */
  msg("pixelmap: %d pixels in map\n", numpix);

  return(nadj);
}
Ejemplo n.º 5
0
/*------------------------------------------------------------------------------
  If poly1 overlaps poly2, split poly1 into two parts.

  If poly3 is null on input, then the appropriate return value is returned,
  but poly1 is not actually split.

   Input: *poly1, poly2 are 2 polygons.
	  mtol = initial angular tolerance within which to merge multiple intersections.
  Output: If **poly3 is not null on input, then:
	      *poly1 and *poly3 are 2 split polygons of poly1, if poly1 is split,
		    with *poly1 the part outside poly2,
		    and *poly3 the part intersecting poly2;
	      *poly1 and *poly3 remain untouched if poly1 is not split.
	  If **poly3 is null on input, then *poly1 remains untouched.
  Return value: -1 = error occurred;
		0 = poly1 and poly2 have zero intersection;
		1 = poly2 fully encloses poly1;
		2 = poly2 splits poly1 into two.
*/
int split_poly(polygon **poly1, polygon *poly2, polygon **poly3, long double mtol)
{
    static polygon *poly = 0x0, *poly4 = 0x0;

    int ier, ip, iprune, np, np1, verb;
    long double area, area_tot, cm, tol,area1,area3,area4;

    /* poly2 is whole sphere, therefore contains poly1 */
    if (poly2->np == 0){
      return(1);
    }
    
    /* make sure poly contains enough space for intersection */
    np = (*poly1)->np + poly2->np;
    ier = room_poly(&poly, np, DNP, 0);
    if (ier == -1) goto out_of_memory;

    /* intersection of poly1 and poly2 */
    poly_poly(*poly1, poly2, poly);

    /* suppress coincident boundaries, to make garea happy */
    iprune = trim_poly(poly);

    /* intersection of poly1 and poly2 is null polygon */
    if (iprune >= 2) return(0);

    /* area of intersection */
    tol = mtol;
    verb = 1;
    ier = garea(poly, &tol, verb, &area_tot);
    if (ier) goto error;

    /* poly1 and poly2 have zero intersection */
    if (area_tot == 0.) return(0);

    /* area of poly1 */
    tol = mtol;
    verb = 1;
    ier = garea(*poly1, &tol, verb, &area1);
    if (ier) goto error;

    /* number of caps of poly1 */
    np1 = (*poly1)->np; 

    /* find boundary of poly2 which intersects poly1 */
    verb = 0;

    for (ip = 0; ip < poly2->np; ip++) {

	cm = poly->cm[np1 + ip];
	poly->cm[np1 + ip] = 2.;		/* suppress boundary to be tested */
	tol = mtol;
	ier = garea(poly, &tol, verb, &area);	/* area of intersection sans boundary */
	poly->cm[np1 + ip] = cm;		/* restore tested boundary */

	if (area > area_tot) {			/* boundary intersects poly1 */
	  /* poly2 splits poly1, but do not actually split */
	  if (!poly3) return(2);

	  /* number of caps of poly1 with extra boundary */
	  np = np1 + 1;
	  
	  /* make sure poly3 contains enough space */
	  ier = room_poly(poly3, np, DNP, 0);
	  
	  if (ier == -1) goto out_of_memory;	  
	  
	  /* poly3 is intersection of poly1 and ip'th cap of poly2 */
	  poly_polyn(*poly1, poly2, ip, 1, *poly3);
	  
	  /* prune poly3 */
	  iprune = prune_poly(*poly3, mtol);
	  if (iprune == -1) goto error;
	  /* poly3 may be null because of roundoff: skip to next cap */
	  if (iprune >= 2) continue;
	  
	  /* area of poly3 */
	  tol = mtol;
	  verb = 1;
	  ier = garea(*poly3, &tol, verb, &area3);
	  if (ier) goto error;

	  /* check to make sure area of poly3 is less than poly1; if not, skip to next cap*/
	  if(area3>=area1) continue;

	  /* make sure poly4 contains enough space */
	  ier = room_poly(&poly4, np, DNP, 1);
	  if (ier == -1) goto out_of_memory;
	  
	  /* poly4 is intersection of poly1 and complement of ip'th cap of poly2 */
	  poly_polyn(*poly1, poly2, ip, -1, poly4);
	  
	  /* prune poly4 */
	  iprune = prune_poly(poly4, mtol);
	  if (iprune == -1) goto error;
	  /* poly4 may be null because of roundoff: skip to next cap */
	  if (iprune >= 2) continue;
	  
	   /* area of poly4 */
	  tol = mtol;
	  verb = 1;
	  ier = garea(poly4, &tol, verb, &area4);
	  if (ier) goto error;

	  /* check to make sure area of poly3 is less than poly1; if not, skip to next cap*/
	  if(area4>=area1) continue;

	  /* make sure poly1 contains enough space */
	  np = poly4->np;
	  ier = room_poly(poly1, np, DNP, 0);
	  if (ier == -1) goto out_of_memory;
	  
	  /* copy poly4 into poly1 */
	  copy_poly(poly4, *poly1);
	  
	  /* poly1 successfully split into poly1 and poly3 */
	  return(2);

	} else if (area < area_tot) {
	    /* area should be >= area_tot because suppressing a boundary of poly should always increase its area;
	       but this can happen because of roundoff */
	    //fprintf(stderr, "split_poly: area %.16Lg of polygon with boundary %d suppressed should be >= area %.16Lg of polygon\n", area, ip, area_tot);
	}
    }
    
    /* poly2 contains poly1 */
     return(1);

    /* ---------------- error returns ---------------- */
    error:
    return(-1);

    out_of_memory:
    fprintf(stderr, "split_poly: failed to allocate memory for polygon of %d caps\n", np + DNP);
    return(-1);
}