/*------------------------------------------------------------------------------ Write midpoints. 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_midpoint(char *filename, format *fmt, int npolys, polygon *polys[/*npolys*/], int npolyw) { const int per = 0; const int nve = 2; const int do_vcirc = 0; char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN]; int i, idmin, idmax, idwidth, ier, imid, ipoly, ivm, nev, nev0, npoly, nv, nvm, width; int *ipv, *gp, *ev; double tol; double *angle; vec *ve, *vm; azel v; FILE *file; /* open filename for writing */ if (!filename || strcmp(filename, "-") == 0) { file = stdout; } else { file = fopen(filename, "w"); if (!file) { fprintf(stderr, "wr_midpoint: cannot open %s for writing\n", filename); return(-1); } } /* largest width of polygon id number */ idmin = 0; idmax = 0; for (ipoly = 0; ipoly < npolys; ipoly++) { if (!polys[ipoly]) continue; if (polys[ipoly]->id < idmin) idmin = polys[ipoly]->id; if (polys[ipoly]->id > idmax) idmax = polys[ipoly]->id; } idmin = ((idmin < 0)? floor(log10((double)-idmin)) + 2 : 1); idmax = ((idmax > 0)? floor(log10((double)idmax)) + 1 : 1); idwidth = ((idmin > idmax)? idmin : idmax); /* write header */ wrangle(0., fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, az_str); width = strlen(az_str); if (fmt->outunitp == 'h') { sprintf(az_str, "az(hms)"); sprintf(el_str, "el(dms)"); } else { sprintf(az_str, "az(%c)", fmt->outunitp); sprintf(el_str, "el(%c)", fmt->outunitp); } fprintf(file, "midpoint of %d polygons\n", npolyw); fprintf(file, "%*s %*s %*s\n", width, az_str, width, el_str, idwidth, "id"); npoly = 0; for (ipoly = 0; ipoly < npolys; ipoly++) { /* discard null polygons */ if (!polys[ipoly]) continue; /* point somewhere in the middle of the polygon */ tol = mtol; ier = gverts(polys[ipoly], do_vcirc, &tol, per, nve, &nv, &ve, &angle, &ipv, &gp, &nev, &nev0, &ev); if (ier == -1) return(-1); imid = vmid(polys[ipoly], tol, nv, nve, ve, ipv, ev, &nvm, &vm); if (imid == -1) return(-1); /* check found a point inside the polygon */ imid = 0; for (ivm = 0; ivm < nvm; ivm++) { if (vm[ivm][0] != 0. || vm[ivm][1] != 0. || vm[ivm][2] != 0.) { imid = 1; if (ivm > 0) for (i = 0; i < 3; i++) vm[0][i] = vm[ivm][i]; break; } } /* found a point */ if (imid == 1) { rp_to_azel(vm[0], &v); switch (fmt->outphase) { case '+': if (v.az < 0.) v.az += TWOPI; break; case '-': if (v.az > PI) v.az -= TWOPI; break; } scale_azel(&v, 'r', fmt->outunitp); } /* write midpoint of polygon */ wrangle(v.az, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, az_str); wrangle(v.el, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, el_str); fprintf(file, "%s %s %*d\n", az_str, el_str, idwidth, polys[ipoly]->id); /* increment polygon count */ npoly++; } /* advise */ msg("%d midpoints written to %s\n", npoly, (file == stdout)? "output": filename); /* close file */ if (file != stdout) fclose(file); return(npoly); }
/*------------------------------------------------------------------------------ Weight polygons. Input: poly = array of pointers to polygons. npoly = pointer to number of polygons. survey = name of survey, or of filename containing list of weights. Output: polys = array of pointers to polygons; Return value: number of polygons weighted, or -1 if error occurred. */ int weight(int npoly, polygon *poly[/*npoly*/], char *survey) { const int per = 0; const int nve = 2; int do_vcirc, i, imid, ipoly, iverts, ivm, nev, nev0, nomid, nv, nvm, nzero; int *ipv, *gp, *ev; long double tol; long double *angle; vec *ve, *vm; azel v; nomid = 0; nzero = 0; for (ipoly = 0; ipoly < npoly; ipoly++) { /* vertices of polygon */ do_vcirc = 0; tol = mtol; iverts = gverts(poly[ipoly], do_vcirc, &tol, per, nve, &nv, &ve, &angle, &ipv, &gp, &nev, &nev0, &ev); if (iverts != 0) return(-1); /* point somewhere in the middle of the polygon */ imid = vmid(poly[ipoly], tol, nv, nve, ve, ipv, ev, &nvm, &vm); if (imid == -1) return(-1); /* check found a point inside the polygon */ imid = 0; for (ivm = 0; ivm < nvm; ivm++) { if (vm[ivm][0] != 0. || vm[ivm][1] != 0. || vm[ivm][2] != 0.) { imid = 1; if (ivm > 0) for (i = 0; i < 3; i++) vm[0][i] = vm[ivm][i]; break; } } /* found a point */ if (imid == 1) { /* convert unit vector to az, el */ rp_to_azel(*vm, &v); /* scale angles from radians to degrees */ scale_azel(&v, 'r', 'd'); /* weight at that point */ poly[ipoly]->weight = weight_fn(v.az, v.el, survey); if (poly[ipoly]->weight == 0.) nzero++; /* failed to find a point */ } else { //call weight_fn to stay in right place in weight file if reading from weights from a file weight_fn(v.az, v.el, survey); if (nomid == 0) msg("weight: failed to find interior point for the following polygons:\n"); msg(" %lld", (fmt.newid == 'n')? (long long)ipoly+fmt.idstart : poly[ipoly]->id); nomid++; } } if (nomid > 0) msg("\n"); if (nomid > 0) { msg("weight: failed to find interior point for %d polygons\n", nomid); msg("FAILURE TO FIND INTERIOR POINT PROBABLY MEANS YOU HAVE A WEIRD-SHAPED POLYGON.\n"); msg("PLEASE FILL IN THE CORRECT WEIGHT BY HAND.\n"); } /* assign new polygon id numbers in place of inherited ids */ if (fmt.newid == 'n') { for (ipoly = 0; ipoly < npoly; ipoly++) { poly[ipoly]->id = (long long)ipoly+fmt.idstart; } } if (fmt.newid == 'p') { for (ipoly = 0; ipoly < npoly; ipoly++) { poly[ipoly]->id = (long long)poly[ipoly]->pixel; } } /* warn about zero weights */ if (nzero > 0) msg("weight: %d polygons have zero weight\n", nzero); return(npoly); }
/*------------------------------------------------------------------------------ Write mask data in edges or vertices 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_edge(char *filename, format *fmt, int npolys, polygon *polys[/*npolys*/], int npolyw) { const int per = 0; const int nve = 2; const char *edges_fmt = "edges %d ( %d points/edge, %d edges, %.15lg weight, %s %s mid):\n"; const char *graphics_fmt = "graphics %d ( %d points, %d edges, %.15lg weight, %s %s mid):\n"; const char *vertices_fmt = "vertices %d ( %d vertices, %.15lg weight, %s %s mid):\n"; char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN]; int do_vcirc, i, ier, imid, ipoly, iv, ive, ivm, jv, manybounds, nbadverts, nev, nev0, npoly, npt, nv, nvm; int *ipv, *gp, *ev; double azo, tol; double *angle; vec *ve, *vm; azel v; FILE *file; /* open filename for writing */ if (!filename || strcmp(filename, "-") == 0) { file = stdout; } else { file = fopen(filename, "w"); if (!file) { fprintf(stderr, "wr_edge: cannot open %s for writing\n", filename); return(-1); } } /* whether to write vertices also for circles with no intersections */ if (strcmp(fmt->out, "vertices") == 0) { do_vcirc = 0; } else { do_vcirc = 1; } /* write number of polygons */ fprintf(file, "%d polygons\n", npolyw); /* write angular unit */ fprintf(file, "unit %c\n", fmt->outunitp); manybounds = 0; npoly = 0; nbadverts = 0; for (ipoly = 0; ipoly < npolys; ipoly++) { /* discard null polygons */ if (!polys[ipoly]) continue; /* point somewhere in the middle of the polygon */ tol = mtol; ier = gverts(polys[ipoly], do_vcirc, &tol, per, nve, &nv, &ve, &angle, &ipv, &gp, &nev, &nev0, &ev); if (ier == -1) return(-1); imid = vmid(polys[ipoly], tol, nv, nve, ve, ipv, ev, &nvm, &vm); if (imid == -1) return(-1); /* check found a point inside the polygon */ imid = 0; for (ivm = 0; ivm < nvm; ivm++) { if (vm[ivm][0] != 0. || vm[ivm][1] != 0. || vm[ivm][2] != 0.) { imid = 1; if (ivm > 0) for (i = 0; i < 3; i++) vm[0][i] = vm[ivm][i]; break; } } /* found a point */ if (imid == 1) { rp_to_azel(vm[0], &v); switch (fmt->outphase) { case '+': if (v.az < 0.) v.az += TWOPI; break; case '-': if (v.az > PI) v.az -= TWOPI; break; } scale_azel(&v, 'r', fmt->outunitp); } /* points on edges of polygon */ tol = mtol; ier = gverts(polys[ipoly], do_vcirc, &tol, fmt->outper, fmt->outnve, &nv, &ve, &angle, &ipv, &gp, &nev, &nev0, &ev); if (ier == -1) return(-1); if (ier) { nbadverts++; continue; } /* warn about multi-boundary polygon */ if (nev > 1) { if (WARNMAX > 0 && manybounds == 0) { msg("the following polygons have > 1 boundary (not simply-connected)\n"); msg(" separate boundaries will be split over separate lines:\n"); } if (manybounds < WARNMAX) { msg(" %d", polys[ipoly]->id); } else if (manybounds == WARNMAX) { msg(" ... more\n"); } manybounds++; } /* count number of points */ npt = 0; for (iv = jv = 0; iv < nv; jv++) { for (; iv < ev[jv]; iv++) { for (ive = 0; ive < fmt->outnve; ive++) { i = iv * fmt->outnve + ive; if (ve[i][0] == 0. && ve[i][1] == 0. && ve[i][2] == 0.) break; npt++; } } } /* number of edges, weight, and midpoint of polygon */ wrangle(v.az, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, az_str); wrangle(v.el, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, el_str); if (strcmp(fmt->out, "edges") == 0) { fprintf(file, edges_fmt, polys[ipoly]->id, fmt->outnve, nv, polys[ipoly]->weight, az_str, el_str); } else if (strcmp(fmt->out, "graphics") == 0) { fprintf(file, graphics_fmt, polys[ipoly]->id, npt, nv, polys[ipoly]->weight, az_str, el_str); } else { fprintf(file, vertices_fmt, polys[ipoly]->id, nv, polys[ipoly]->weight, az_str, el_str); } /* write points, splitting separate boundaries over separate lines */ for (iv = jv = 0; iv < nv; jv++) { for (; iv < ev[jv]; iv++) { for (ive = 0; ive < fmt->outnve; ive++) { i = iv * fmt->outnve + ive; if (ve[i][0] == 0. && ve[i][1] == 0. && ve[i][2] == 0.) break; /* convert unit vector to azel vertex */ rp_to_azel(ve[i], &v); /* set azimuth of first point */ if (iv == 0 && ive == 0) { switch (fmt->outphase) { case '+': if (v.az < 0.) v.az += TWOPI; break; case '-': if (v.az > PI) v.az -= TWOPI; break; } /* phase azimuth of each subsequent point to the previous point */ } else { v.az -= rint((v.az - azo) / TWOPI) * TWOPI; } azo = v.az; scale_azel(&v, 'r', fmt->outunitp); wrangle(v.az, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, az_str); wrangle(v.el, fmt->outunitp, fmt->outprecision, AZEL_STR_LEN, el_str); fprintf(file, " %s %s", az_str, el_str); } } fprintf(file, "\n"); } /* increment polygon count */ npoly++; } /* warn about multi-boundary polygon */ if (WARNMAX > 0 && manybounds > 0 && manybounds <= WARNMAX) msg("\n"); if (manybounds > 0) msg("%d polygons had more than one boundary (not simply-connected)\n", manybounds); /* warn about polygons producing fatal error */ if (nbadverts > 0) { msg("%d polygons producing fatal error in gvert discarded\n"); } /* advise */ msg("%d polygons written to %s\n", npoly, (file == stdout)? "output": filename); /* close file */ if (file != stdout) fclose(file); return(npoly); }