home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)psmask.c 2.28 30 Jun 1995
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /*
- * psmask tries to achieve masking using one of two different approachs:
- * The default way of operation is: Instead of painting tiles where there's no
- * data [or where there is data] psmask uses contouring to find the polygons
- * that contain the data [or contain the regions with no data]. For many types
- * of data coverage, this results in a managable path instead of thousands of
- * tiles. So, instead of painting polygons, psmask sets up actual clip paths.
- * As an option, the user may specify a rgb combination to fill the clipped areas.
- * To avoid having to deal with the problems that arise if the data distribution
- * is such that part of the map boundary should be part of the clip paths, we
- * internally enlarge the grid by one gridsize unit so no nodes along the edges
- * have data. Before using the clippaths we move points outside the real region
- * onto the boundary.
- * Should the paths be too long for PostScript to handle, the user may override
- * the default with the -T switch. Then, masking is achieved using tiling
- *
- * Author: Paul Wessel
- * Date: 21-NOV-1990
- * Version: 2.0
- * Limitation: Total clip path cannot exceed PostScript max path length (~1350).
- * If it does, the -T option be used instead. Path length can be
- * reduced by choosing a coarser grid spacing.
- *
- */
-
- #include "gmt.h"
-
- #define IJ(i,j) ((i) + (j) * nx)
-
- /* Global variables for contour_sub routines */
-
- int p[5], i_off[5], j_off[5], k_off[5], offset;
- unsigned int bit[32];
-
- char *grd;
- int *edge;
- double *x, *y; /* Arrays holding the contour xy values */
- double *x_grid, *y_grid;
-
- main (argc, argv)
- int argc;
- char **argv; {
- int i, j, ij, n, nm, n_edges, di, dj, ii, jj;
- int nx, ny, section, n_alloc, ix, iy, n_fields;
-
- BOOLEAN error = FALSE, first = TRUE, dump = FALSE, invert = FALSE, binary = FALSE, more;
- BOOLEAN end_of_clip = FALSE, find_paths = TRUE, use_poly, single_precision = FALSE;
-
- char dfile[80], line[100];
-
- double west, east, north, south, dx, dy, radius = 0.0, *in;
- double x0, y0, x1, y1, xx[4], yy[4], dummy;
-
- FILE *fp = NULL;
-
- struct FILL fill;
-
- west = east = north = south = 0.0;
-
- argc = gmt_begin (argc, argv);
-
- gmt_init_fill (&fill, -1, -1, -1);
- dfile[0] = 0;
- dx = dy = 0.0;
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
-
- /* Common parameters */
-
- case 'B':
- case 'J':
- case 'K':
- case 'O':
- case 'P':
- case 'R':
- case 'U':
- case 'V':
- case 'X':
- case 'x':
- case 'Y':
- case 'y':
- case 'c':
- case ':':
- case '\0':
- error += get_common_args (argv[i], &west, &east, &south, &north);
- break;
-
- /* Supplemental parameters */
-
- case 'b': /* Input pairs are binary, not ascii */
- single_precision = !(argv[i][strlen(argv[i])-1] == 'd');
- binary = TRUE;
- break;
- case 'C': /* Radius of influence */
- gmt_getinc(&argv[i][2], &radius, &radius);
- break;
- case 'D': /* Dump the polygons to files */
- strcpy (dfile, &argv[i][2]);
- dump = TRUE;
- break;
- case 'E':
- sscanf (&argv[i][2], "%lf/%lf", &z_project.view_azimuth, &z_project.view_elevation);
- break;
- case 'F':
- if (gmt_getrgb (&argv[i][2], &gmtdefs.basemap_frame_rgb[0], &gmtdefs.basemap_frame_rgb[1], &gmtdefs.basemap_frame_rgb[2])) {
- gmt_pen_syntax ('F');
- error++;
- }
- break;
- case 'G':
- if (gmt_getfill (&argv[i][2], &fill)) {
- gmt_fill_syntax ('G');
- error++;
- }
- break;
- case 'I':
- gmt_getinc (&argv[i][2], &dx, &dy);
- break;
- case 'N':
- invert = TRUE;
- break;
- case 'S':
- end_of_clip = TRUE;
- break;
- case 'T':
- find_paths = FALSE;
- break;
- default:
- error = TRUE;
- gmt_default_error (argv[i][1]);
- break;
- }
- }
- else {
- if ((fp = fopen(argv[i], "r")) == NULL) {
- fprintf (stderr, "psmask: Could not open file %s\n", argv[i]);
- exit(-1);
- }
- }
- }
-
- if (argc == 1 || gmt_quick) {
- fprintf (stderr,"psmask %s - Clipping of 2-D data sets\n\n", GMT_VERSION);
- fprintf (stderr, "usage: psmask <xyz-file> -I<xinc>[m|c][/<yinc>[m|c]] -J<params> -R<west/east/south/north>\n");
- fprintf (stderr, " [-B<tickinfo>] [-C<radius>[m|c]] -D<file> [-Eaz/el] [-F<r/g/b] [-G<fill>] [-K] [-N]\n");
- fprintf (stderr, " [-O] [-P] [-S] [-T] [-U[<label>]] [-V] [-X<x_shift>] [-Y<y_shift>] [-c<ncopies>][ -:] [-b[d]]\n\n");
-
- if (gmt_quick) exit(-1);
-
- fprintf (stderr, " <xyz-file> is the datafile. If not given, read standard input\n");
- fprintf (stderr, " -I sets grid increments; enter xinc, optionally xinc/yinc.\n");
- fprintf (stderr, " Default is yinc = xinc. Append an m [or s] to xinc or yinc to indicate minutes [or seconds]\n");
- explain_option ('j');
- explain_option ('R');
- fprintf (stderr, "\n\tOPTIONS:\n");
- explain_option ('b');
- fprintf (stderr, " -C Circle of influence. Nodes inside circles of <radius> centered on\n");
- fprintf (stderr, " the input data poins are considered to be reliable estimates of the surface\n");
- fprintf (stderr, " Default is -C0, i.e., only the nearest node is considered reliable\n");
- fprintf (stderr, " <radius> is in the same units as x and y\n");
- fprintf (stderr, " Append an m [or c] to indicate minutes [or seconds]\n");
- fprintf (stderr, " -D dumps the clip-paths to files using the prefix <file>_\n");
- fprintf (stderr, " Ignored if -T is specified\n");
- fprintf (stderr, " -E set azimuth and elevation of viewpoint for 3-D perspective [180/90]\n");
- fprintf (stderr, " -S means stop existing clip-path (Only with -O) \n");
- fprintf (stderr, " -F Set color used for Frame and anotation [%d/%d/%d]\n",
- gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
- fprintf (stderr, " -G sets fill color r/g/b [Default is no fill]\n");
- explain_option ('K');
- fprintf (stderr, " -N will invert the sense of the clipping [or tiling]\n");
- explain_option ('O');
- explain_option ('P');
- fprintf (stderr, " -T will paint tiles. [Default will trace data outline]\n");
- fprintf (stderr, " If set you must also specify a color/fill with -G\n");
- fprintf (stderr, " !May only be used with linear, Mercator, and basic cylindrical projections!\n");
- explain_option ('U');
- explain_option ('V');
- explain_option ('X');
- explain_option ('c');
- explain_option (':');
- fprintf (stderr, "\t-b means input data are binary. [Default is ascii]\n");
- fprintf (stderr, "\t Append d for double precision [Default is single].\n");
- explain_option ('.');
- exit(-1);
- }
-
- if (!end_of_clip) {
- if (z_project.view_azimuth > 360.0 || z_project.view_elevation <= 0.0 || z_project.view_elevation > 90.0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -E option: Enter azimuth in 0-360 range, elevation in 0-90 range\n", gmt_program);
- error++;
- }
- if (!project_info.region_supplied) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify -R option\n", gmt_program);
- error++;
- }
- if (!find_paths && !RECT_GRATICULE) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -T option: Only available with Linear, Mercator, or basic cylindrical projections\n", gmt_program);
- error++;
- }
- if (!find_paths && fill.r == -1) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -T option: Must also specify a tile color with -G\n", gmt_program);
- error++;
- }
- if (find_paths && fill.use_pattern) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -G option: Pattern fill not supported\n", gmt_program);
- error++;
- }
- if (dx <= 0.0 || dy <= 0.0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -I option: Must specify positive increments\n", gmt_program);
- error++;
- }
- if (radius < 0.0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -C option: Radius must be positive\n", gmt_program);
- error++;
- }
- }
- if (binary && gmtdefs.io_header) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR. Binary input data cannot have header -H\n", gmt_program);
- error++;
- }
-
- if (error) exit (-1);
-
- if (binary) gmt_input = (single_precision) ? bin_float_input : bin_double_input;
-
- if (end_of_clip) gmtdefs.overlay = TRUE; /* Force overlay mode */
- if (!project_info.x_off_supplied && gmtdefs.overlay) gmtdefs.x_origin = 0.0;
- if (!project_info.y_off_supplied && gmtdefs.overlay) gmtdefs.y_origin = 0.0;
-
- ps_plotinit (CNULL, gmtdefs.overlay, gmtdefs.page_orientation, gmtdefs.x_origin, gmtdefs.y_origin,
- gmtdefs.global_x_scale, gmtdefs.global_y_scale, gmtdefs.n_copies,
- gmtdefs.dpi, gmtdefs.measure_unit, gmtdefs.paper_width, gmtdefs.page_rgb, gmt_epsinfo (argv[0]));
- echo_command (argc, argv);
- if (gmtdefs.unix_time) timestamp (argc, argv);
-
- if (!end_of_clip) { /* Start new clip_path */
-
- map_setup (west, east, south, north);
-
- if (project_info.three_D) ps_transrotate (-z_project.xmin, -z_project.ymin, 0.0);
-
- if (gmtdefs.verbose) fprintf (stderr, "psmask: Allocate memory, read and process data file\n");
-
- ix = (gmtdefs.xy_toggle) ? 1 : 0; iy = 1 - ix; /* Set up which columns have x and y */
-
- /* Enlarge region by 1 row/column */
-
- west -= dx; east += dx; south -= dy; north += dy;
-
- nx = rint ((east - west)/dx) + 1;
- ny = rint ((north - south)/dy) + 1;
-
- nm = nx * ny;
- grd = (char *) memory (CNULL, nm, sizeof (char), "psmask");
-
- di = rint (0.5 * radius / dx);
- dj = rint (0.5 * radius / dy);
- if (fp == NULL) fp = stdin;
- if (gmtdefs.io_header) for (i = 0; i < gmtdefs.n_header_recs; i++) fgets (line, 512, fp);
-
- while ((n_fields = gmt_input (fp, 3, &in)) == 3) {
- i = rint ((in[ix] - west)/dx);
- if (i < 0 || i >= nx) continue;
- j = rint ((north - in[iy])/dy);
- if (j < 0 || j >= ny) continue;
- x0 = west + i * dx;
- y0 = north - j * dy;
-
- for (ii = i - di; ii <= i + di; ii++) {
- if (ii < 0 || ii >= nx) continue;
- x1 = west + ii * dx;
- for (jj = j - dj; jj <= j + dj; jj++) {
- if (jj < 0 || jj >= ny) continue;
- y1 = north - jj * dy;
- if (hypot (x1 - x0, y1 - y0) > radius) continue;
- grd[jj*nx+ii] = 1;
- }
- }
- }
- if (fp != stdin) fclose (fp);
-
- if (invert) for (i = 0; i < nm; i++) grd[i] = 1 - grd[i]; /* Reverse sense of test */
-
- /* Force perimeter nodes to be FALSE */
-
- for (i = 0, ij = (ny-1) * nx; i < nx; i++) grd[i] = grd[i+ij] = FALSE;
- for (j = 0; j < ny; j++) grd[j*nx] = grd[(j+1)*nx-1] = FALSE;
-
- if (find_paths) { /* Must trace the outline of ON/OFF values in grd */
- x = (double *) memory (CNULL, GMT_CHUNK, sizeof (double), "psmask");
- y = (double *) memory (CNULL, GMT_CHUNK, sizeof (double), "psmask");
- n_alloc = GMT_CHUNK;
-
- n_edges = ny * (int )ceil (nx / 16.0);
- edge = (int *) memory (CNULL, n_edges, sizeof (int), "psmask");
-
- if (frame_info.plot) {
- ps_setpaint (gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
- map_basemap ();
- ps_setpaint (gmtdefs.background_rgb[0], gmtdefs.background_rgb[1], gmtdefs.background_rgb[2]);
- }
-
- if (gmtdefs.verbose) fprintf (stderr, "psmask: Tracing the clip path\n");
-
- section = 0;
- first = TRUE;
- while ((n = clip_contours (grd, nx, ny, west, north, dx, dy, edge, first, &x, &y, &n_alloc)) > 0) {
- shrink_clip_contours (x, y, n);
- if (dump) dump_clip_countours (x, y, n, section, dfile);
- draw_clip_contours (x, y, n, fill.r, fill.g, fill.b, section, first);
- first = FALSE;
- section++;
- }
-
- draw_clip_contours (x, y, 0, fill.r, fill.g, fill.b, section, 2); /* Activate clip-path */
-
- free ((char *)edge);
- free ((char *)x);
- free ((char *)y);
- }
- else { /* Just paint tiles */
- if (gmtdefs.verbose) fprintf (stderr, "psmask: Tiling...\n");
- x_grid = (double *) memory (CNULL, nx, sizeof (double), "psmask");
- y_grid = (double *) memory (CNULL, ny, sizeof (double), "psmask");
- for (i = 2; i < nx - 1; i++) geo_to_xy (west + (i - 0.5) * dx, south + dy, &x_grid[i], &dummy);
- for (j = 2; j < ny - 1; j++) geo_to_xy (west + dx, north - (j - 0.5) * dy, &dummy, &y_grid[j]);
- geo_to_xy (west + dx, north - dy, &x_grid[1], &y_grid[1]);
- geo_to_xy (east - dx, south + dy, &x_grid[nx-1], &y_grid[ny-1]);
-
- use_poly = (fill.use_pattern || project_info.three_D);
-
- for (j = 1; j < ny; j++) {
- ij = j * nx + 1;
- for (i = 1; i < nx; i++, ij++) {
- if (!grd[ij]) continue;
-
- if (use_poly) {
- xx[0] = xx[3] = x_grid[i]; xx[1] = xx[2] = x_grid[i+1];
- yy[0] = yy[1] = y_grid[j+1]; yy[2] = yy[3] = y_grid[j];
- if (project_info.three_D) two_d_to_three_d (xx, yy, 4);
- }
-
- if (fill.use_pattern)
- ps_imagefill (xx, yy, 4, fill.pattern_no, fill.pattern, fill.inverse, fill.icon_size, FALSE);
- else if (project_info.three_D)
- ps_polygon (xx, yy, 4, fill.r, fill.g, fill.b, FALSE);
- else
- ps_rect (x_grid[i], y_grid[j+1], x_grid[i+1], y_grid[j], fill.r, fill.g, fill.b, FALSE);
- }
- }
-
- free ((char *)x_grid);
- free ((char *)y_grid);
-
- if (frame_info.plot) {
- ps_setpaint (gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
- map_basemap ();
- }
- }
-
- if (project_info.three_D) ps_rotatetrans (z_project.xmin, z_project.ymin, 0.0);
-
- free ((char *)grd);
- if (gmtdefs.verbose) fprintf (stderr, "psmask: clipping on!\n");
- }
- else { /* Just undo previous clip-path */
- ps_clipoff ();
- if (frame_info.plot) {
- ps_setpaint (gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
- map_basemap ();
- }
- if (gmtdefs.verbose) fprintf (stderr, "psmask: clipping off!\n");
- }
-
- ps_setpaint (gmtdefs.background_rgb[0], gmtdefs.background_rgb[1], gmtdefs.background_rgb[2]);
-
- ps_plotend (gmtdefs.last_page);
-
-
- gmt_end (argc, argv);
- }
-
- int draw_clip_contours (xx, yy, nn, r, g, b, id, flag)
- double *xx, *yy;
- int nn, r, g, b, id, flag; {
- int i;
- double x, y;
-
- if (nn < 2 && flag < 2) return;
-
- for (i = 0; i < nn; i++) {
- x = xx[i]; y = yy[i];
- geo_to_xy (x, y, &xx[i], &yy[i]);
- }
- nn = compact_line (xx, yy, nn, FALSE, 0);
-
- if (project_info.three_D) two_d_to_three_d (xx, yy, nn);
-
- if (nn > 0) printf ("%% Start of clip path sub-segment %d\n", id);
- ps_clipon (xx, yy, nn, r, g, b, flag);
- if (nn > 0) printf ("%% End of clip path sub-segment %d\n", id);
-
- }
-
- int dump_clip_countours (xx, yy, nn, id, file)
- double *xx, *yy;
- char *file;
- int nn, id; {
- int i;
- char fname[512], format[80];
- FILE *fp;
-
- if (nn < 2) return;
-
- sprintf (format, "%s\t%s\n\0", gmtdefs.d_format, gmtdefs.d_format);
- sprintf (fname, "%s_%d.xy\0", file, id);
- fp = fopen (fname, "w");
- for (i = 0; i < nn; i++) fprintf (fp, format, xx[i], yy[i]);
- fclose (fp);
- }
-
- int clip_contours (grd, nx, ny, west, north, dx, dy, edge, first, x, y, max)
- char grd[];
- int nx, ny, first, *max;
- double west, north, dx, dy;
- int edge[];
- double *x[], *y[]; {
- /* The routine finds the zero-contour in the grd dataset. it assumes that
- * no node has a value exactly == 0.0. If more than max points are found
- * trace_clip_contours will try to allocate more memory in blocks of 1000 points
- */
-
- static int i0, j0;
- int i, j, ij, n = 0, n_edges, edge_word, edge_bit;
- BOOLEAN go_on = TRUE;
-
-
- n_edges = ny * (int) ceil (nx / 16.0);
- offset = n_edges / 2;
-
- /* Reset edge-flags to zero, if necessary */
- if (first) {
- i0 = j0 = 0;
- p[0] = p[4] = 0; p[1] = 1; p[2] = 1 - nx; p[3] = -nx;
- i_off[0] = i_off[2] = i_off[3] = i_off[4] = 0; i_off[1] = 1;
- j_off[0] = j_off[1] = j_off[3] = j_off[4] = 0; j_off[2] = -1;
- k_off[0] = k_off[2] = k_off[4] = 0; k_off[1] = k_off[3] = 1;
- for (i = 1, bit[0] = 1; i < 32; i++) bit[i] = bit[i-1] << 1;
- }
-
- /* Loop over interior boxes */
-
- for (j = j0; go_on && j < ny; j++) {
- ij = i0 + j * nx;
- for (i = i0; go_on && i < nx-1; i++, ij++) {
- edge_word = ij / 32 + offset;
- edge_bit = ij % 32;
- if (!(edge[edge_word] & bit[edge_bit]) && ((grd[ij]+grd[ij-nx]) == 1)) { /* Start tracing countour */
- *x[0] = west + i*dx;
- *y[0] = north - (j-0.5) * dy;
- edge[edge_word] |= bit[edge_bit];
- n = trace_clip_contours (grd, nx, edge, west, north, dx, dy, x, y, i, j, 3, max);
- go_on = FALSE;
- i0 = i + 1;
- j0 = j;
- }
- }
- if (!go_on) i0 = 1;
- }
-
- return (n);
- }
-
- int trace_clip_contours (grd, nx, edge, west, north, dx, dy, xx, yy, i, j, kk, max)
- char grd[];
- int nx, i, j, kk, *max;
- int edge[];
- double west, north, dx, dy;
- double **xx, **yy; {
- int n = 1, k, k0, ij, ij0, n_cuts, kk_opposite, first_k, more;
- int edge_word, edge_bit, m;
- double xk[4], yk[4], x0, y0;
-
- m = *max - 2;
-
- more = TRUE;
- do {
- ij = i + j * nx;
- x0 = west + i * dx;
- y0 = north - j * dy;
- n_cuts = 0;
- k0 = kk;
-
- for (k = 0; k < 4; k++) { /* Loop over box sides */
-
- /* Skip where we already have a cut (k == k0) */
-
- if (k == k0) continue;
-
- /* Skip edge already has been used */
-
- ij0 = IJ (i + i_off[k], j + j_off[k]);
- edge_word = ij0 / 32 + k_off[k] * offset;
- edge_bit = ij0 % 32;
- if (edge[edge_word] & bit[edge_bit]) continue;
-
- /* Skip if no zero-crossing on this edge */
-
- if ((grd[ij+p[k+1]] + grd[ij+p[k]]) != 1) continue;
-
- /* Here we have a crossing */
-
- if (k%2) { /* Cutting a S-N line */
- if (k == 1) {
- xk[1] = x0 + dx;
- yk[1] = y0 + 0.5*dy;
- }
- else {
- xk[3] = x0;
- yk[3] = y0 + 0.5*dy;
- }
- }
- else { /* Cutting a E-W line */
- if (k == 0) {
- xk[0] = x0 + 0.5*dx;
- yk[0] = y0;
- }
- else {
- xk[2] = x0 + 0.5*dx;
- yk[2] = y0 + dy;
- }
- }
- kk = k;
- n_cuts++;
- }
-
- if (n > m) { /* Must try to allocate more memory */
- *max += 1000;
- m += 1000;
- *xx = (double *) memory ((char *)*xx, (*max), sizeof (double), "trace_clip_contours");
- *yy = (double *) memory ((char *)*yy, (*max), sizeof (double), "trace_clip_contours");
- }
- if (n_cuts == 0) { /* Close interior contour and return */
- if (fmod (*xx[0], dx) == 0.0) /* On side 1 or 3 */
- first_k = ((*xx[0] - x0) == 0.0) ? 3 : 1;
- else /* On side 0 or 2 */
- first_k = ((*yy[0] - y0) == 0.0) ? 0 : 2;
- kk_opposite = (first_k + 2) % 4;
- if (k0 != kk_opposite) {
- (*xx)[n] = x0 + 0.5*dx;
- (*yy)[n] = y0 + 0.5*dy;
- n++;
- }
- (*xx)[n] = (*xx)[0];
- (*yy)[n] = (*yy)[0];
- n++;
- more = FALSE;
- }
- else if (n_cuts == 1) { /* Draw a line to this point and keep tracing */
- /* Add center of box if this and previous cut NOT on opposite edges */
- kk_opposite = (k0 + 2) % 4;
- if (kk != kk_opposite) {
- (*xx)[n] = x0 + 0.5*dx;
- (*yy)[n] = y0 + 0.5*dy;
- n++;
- }
- (*xx)[n] = xk[kk];
- (*yy)[n] = yk[kk];
- n++;
- }
- else { /* Saddle point, we decide to connect to the point nearest previous point */
- kk = (k0 + 1)%4; /* Pick next edge since it is arbitrarely where we go */
- /* First add center of box */
- (*xx)[n] = x0 + 0.5*dx;
- (*yy)[n] = y0 + 0.5*dy;
- n++;
- (*xx)[n] = xk[kk];
- (*yy)[n] = yk[kk];
- n++;
- }
- if (more) { /* Mark this edge as used */
- ij0 = IJ (i + i_off[kk], j + j_off[kk]);
- edge_word = ij0 / 32 + k_off[kk] * offset;
- edge_bit = ij0 % 32;
- edge[edge_word] |= bit[edge_bit];
- }
-
- /* Get next box (i,j,kk) */
-
- i -= (kk-2)%2;
- j -= (kk-1)%2;
- kk = (kk+2)%4;
-
- } while (more);
- return (n);
- }
-
- int shrink_clip_contours (x, y, n)
- double x[], y[];
- int n; {
- /* Moves outside points to boundary */
- int i;
-
- for (i = 0; i < n; i++) {
- if (x[i] < project_info.w)
- x[i] = project_info.w;
- if (x[i] > project_info.e)
- x[i] = project_info.e;
- if (y[i] < project_info.s)
- y[i] = project_info.s;
- if (y[i] > project_info.n)
- y[i] = project_info.n;
- }
- }
-
-