home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)pscontour.c 2.22 09 Aug 1995
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /* pscontour will read a file of points in the plane, performs the
- * Delaunay triangulation, and contours these triangles. As an option
- * the user may provide a file with indeces of which vertices constitute
- * the triangles.
- *
- * Author: Paul Wessel
- * Date: 1-JAN-1995
- * Version: 3.0
- *
- */
-
- #include "gmt.h"
-
- /* Macros used below */
- int delta, sum;
- /* Returns plus/minus 1 if node2 is after/before node1 */
- #define get_direction(node_1, node_2) (((delta = (node_2) - (node_1)) == 1 || delta == -2) ? 1 : -1)
- /* Returns the id of the node common to the two edges */
- #define get_node_index(edge_1, edge_2) (((sum = (edge_1) + (edge_2)) == 1) ? 1 : ((sum == 2) ? 0 : 2))
-
- struct PSCONTOUR {
- int n_alloc, nl;
- double val;
- double angle;
- char type;
- struct PSLINE *L;
- } *cont;
-
- struct PSLINE { /* Beginning and end of straight contour segment */
- double x0, y0;
- double x1, y1;
- };
-
- struct CHAIN {
- struct PT *begin;
- struct PT *end;
- struct CHAIN *next;
- };
-
- struct PT {
- double x, y;
- struct PT *next;
- };
-
- struct LABEL {
- double x, y;
- double angle;
- char label[32];
- struct LABEL *next_label, *prev_label;
- } *anchor, *old_label;
-
-
- main(argc, argv)
- int argc;
- char *argv[]; {
- int n, np, nx, i, j, ij, k, kk, k2, k3, way1, way2, node, n1, n2, c, r, g, b;
- int n_alloc, box = 1, section = 0, ix, iy, *ind, *vert, *cind, n_fields, n_contours;
- int add, close, br, bg, bb, label_font_size = 9, bad;
-
- BOOLEAN error = FALSE, image_them = FALSE, draw_contours = FALSE, bin = FALSE, dump = FALSE, clip = TRUE;
- BOOLEAN fix_angle = FALSE, more, t_set = FALSE, single_precision = FALSE, multi_segments = FALSE;
-
- double xx[3], yy[3], zz[3], xout[4], yout[4], *in, west, east, south, north, z_min;
- double *xc, *yc, *zc, *x, *y, *z, *xp, *yp, anot_dist, label_angle = 0.0;
-
- char line[512], *cpt_file = CNULL, *t_file = CNULL, dfile[512], EOL_flag = '>';
-
- FILE *fp = NULL, *fp_d = NULL;
-
- struct PEN pen;
-
- argc = gmt_begin (argc, argv);
-
- gmt_init_pen (&pen, 1);
- anot_dist = 4.0; /* Distance in inches between anotations */
- if (!gmtdefs.measure_unit) anot_dist = 10.0; /* change to cm */
- dfile[0] = 0;
- br = gmtdefs.page_rgb[0]; /* Default box color is page color */
- bg = gmtdefs.page_rgb[1];
- bb = gmtdefs.page_rgb[2];
-
- /* Check and interpret the command line arguments */
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch(argv[i][1]) {
-
- /* Common parameters */
-
- case 'B':
- case 'H':
- 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 'A':
- for (j = 2, bad = 0; argv[i][j] && argv[i][j] != 'f'; j++);
- if (argv[i][j]) { /* Found font size option */
- label_font_size = atoi (&argv[i][j+1]);
- if (label_font_size <= 0) bad++;
- }
-
- for (j = 2; argv[i][j] && argv[i][j] != 'a'; j++);
- if (argv[i][j]) { /* Found fixed angle option */
- label_angle = atof (&argv[i][j+1]);
- fix_angle = TRUE;
- if (label_angle <= -90.0 || label_angle > 180.0) bad++;
- }
-
- for (j = 2; argv[i][j] && argv[i][j] != '/'; j++);
- if (argv[i][j] && gmt_getrgb (&argv[i][j+1], &br, &bg, &bb)) bad++;
- if (strchr (argv[i], 'o')) box = 2;
- if (bad) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -A option. Correct syntax:\n", gmt_program);
- fprintf (stderr, "\t-A[f<fontsize>][a<fixedangle>][/<r/g/b>][o]\n");
- error += bad;
- }
- break;
-
- case 'b':
- single_precision = !(argv[i][strlen(argv[i])-1] == 'd');
- bin = TRUE;
- break;
- case 'C':
- cpt_file = &argv[i][2];
- break;
- case 'D':
- dump = TRUE;
- strcpy (dfile, &argv[i][2]);
- 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++;
- }
- case 'G':
- anot_dist = atof (&argv[i][2]);
- break;
- case 'I':
- image_them = TRUE;
- break;
- case 'M': /* with -D, create one multiple line segments */
- multi_segments = 2;
- if (argv[i][2]) EOL_flag = argv[i][2];
- break;
- case 'N':
- clip = FALSE;
- break;
- case 'T':
- t_file = &argv[i][2];
- t_set = TRUE;
- break;
- case 'W':
- if (gmt_getpen (&argv[i][2], &pen)) {
- gmt_pen_syntax ('W');
- error++;
- }
- else
- draw_contours = TRUE;
- break;
-
- /* Options not recognized */
-
- default:
- error = TRUE;
- gmt_default_error (argv[i][1]);
- break;
- }
- }
- else
- fp = fopen (argv[i], "r");
- }
-
- if (gmt_quick || argc == 1) { /* Display usage */
- fprintf (stderr,"pscontour %s - Contour xyz-data by triangulation\n\n", GMT_VERSION);
- fprintf(stderr,"usage: pscontour <xyzfile> -C<cpt_file> -J<params> -R<west>/<east>/<south>/<north>\n");
- fprintf (stderr, " [-A[f<fontsize>][/r/g/b][a<angle>][o]] [-B<tickinfo>] [-D<dumpfile>] [-E<az>/<el>]\n");
- fprintf (stderr, " [-F<r>/<g>/<b>] [-H] [-I] [-K] [-M[<flag>]] [-N] [-O] [-P] [-T<indexfile>]\n");
- fprintf (stderr, " [-U] [-V] [-W<pen>] [-X<x_shift>] [-Y<y_shift>] [-c<ncopies>] [-:] [-b[d]]\n\n");
-
- if (gmt_quick) exit(-1);
-
- fprintf(stderr," -C Color palette table\n");
- explain_option ('j');
- explain_option ('R');
- fprintf (stderr, "\n\tOPTIONS:\n");
- fprintf (stderr, " -A Annotation format information.\n");
- fprintf (stderr, " Append f followed by desired font size in points [Default is 9].\n");
- fprintf (stderr, " Append /r/g/b to change color of text box [Default is %d/%d/%d]\n", br, bg, bb);
- fprintf (stderr, " Append o to draw outline of text box [Default is no outline]\n");
- fprintf (stderr, " Append a<angle> to force anotations at this fixed angle [Default follows contour]\n");
- explain_option ('b');
- fprintf (stderr, " -D to Dump contour lines to individual files (but see -M)\n");
- fprintf (stderr, " -E set azimuth and elevation of viewpoint for 3-D perspective [180/90]\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 Gap between anotations in %s [Default = %lg]\n", gmt_unit_names[gmtdefs.measure_unit], anot_dist);
- explain_option ('H');
- fprintf (stderr, " -I Color triangles using the cpt file\n");
- explain_option ('K');
- fprintf (stderr, " -M Used with -D. Create a single multiple segment file where contours are separated by a record\n");
- fprintf (stderr, " whose first character is <flag> ['>']. This header also has the contour level value\n");
- fprintf(stderr," -N do NOT clip contours/image at the border [Default clips]\n");
- explain_option ('O');
- explain_option ('P');
- fprintf(stderr," -T file with triplets of point indeces for each triangle\n");
- fprintf(stderr," [Default performs the Delauney triangulation on xyz-data]\n");
- explain_option ('U');
- explain_option ('V');
- fprintf (stderr, " -W selects contouring and sets contour pen attributes\n");
- explain_option ('X');
- explain_option ('c');
- explain_option (':');
- fprintf (stderr, "\t-b means binary input for xyz and node ids (ints)) [ASCII]\n");
- fprintf (stderr, "\t Append d for double precision [Default is single precision].\n"); explain_option ('.');
- explain_option ('.');
- exit(-1);
- }
-
- /* Check that the options selected are mutually consistant */
-
- if (!project_info.region_supplied) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify -R option\n", gmt_program);
- error++;
- }
- if (!(draw_contours || image_them)) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify one of -W or -I\n", gmt_program);
- error++;
- }
- if (!cpt_file) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -C option: Must specify a color palette table\n", gmt_program);
- error++;
- }
- if (t_set && !t_file) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -T option: Must specify an index file\n", gmt_program);
- error++;
- }
- 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 (bin && 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 (bin) gmt_input = (single_precision) ? bin_float_input : bin_double_input;
-
- if (t_set) {
- if ((fp_d = fopen (t_file, "r")) == NULL) {
- fprintf (stderr, "pscontour: Could not open index file %s\n", t_file);
- exit (-1);
- }
- }
-
- if (dump && dfile[0] == 0) {
- fprintf (stderr, "pscontour: contours wil be written to file contour\n");
- strcpy (dfile,"contour");
- }
-
- read_cpt (cpt_file);
- if (image_them && gmt_continuous) {
- fprintf (stderr, "pscontour: -I option requires constant color between contours!\n");
- exit (-1);
- }
-
- map_setup (west, east, south, north);
-
- 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 (project_info.three_D) ps_transrotate (-z_project.xmin, -z_project.ymin, 0.0);
-
- if (clip) map_clip_on (-1, -1, -1, 3);
-
- if (fp == NULL) fp = stdin;
-
- n_alloc = GMT_CHUNK;
- x = (double *) memory (CNULL, n_alloc, sizeof (double), "pscontour");
- y = (double *) memory (CNULL, n_alloc, sizeof (double), "pscontour");
- z = (double *) memory (CNULL, n_alloc, sizeof (double), "pscontour");
-
- if (gmtdefs.io_header) for (i = 0; i < gmtdefs.n_header_recs; i++) fgets (line, 512, fp);
-
- ix = (gmtdefs.xy_toggle) ? 1 : 0; iy = 1 - ix; /* Set up which columns have x and y */
-
- n = 0;
- more = ((n_fields = gmt_input (fp, 3, &in)) == 3);
-
- while (more) {
- if (bad_float (in[2])) continue; /* Skip when z = NaN */
-
- x[n] = in[ix];
- y[n] = in[iy];
- z[n] = in[2];
- n++;
-
- if (n == n_alloc) {
- n_alloc += GMT_CHUNK;
- x = (double *) memory ((char *)x, n_alloc, sizeof (double), "pscontour");
- y = (double *) memory ((char *)y, n_alloc, sizeof (double), "pscontour");
- z = (double *) memory ((char *)z, n_alloc, sizeof (double), "pscontour");
- }
-
- more = ((n_fields = gmt_input (fp, 3, &in)) == 3);
- }
- if (fp != stdin) fclose (fp);
- if (n_fields == -1) n_fields = 0; /* Ok to get EOF */
- if (n_fields%3) { /* Got garbage or multiple segment subheader */
- fprintf (stderr, "%s: Cannot read X Y Z line %d, aborts\n", gmt_program, n);
- exit (-1);
- }
-
- x = (double *) memory ((char *)x, n, sizeof (double), "pscontour");
- y = (double *) memory ((char *)y, n, sizeof (double), "pscontour");
- z = (double *) memory ((char *)z, n, sizeof (double), "pscontour");
-
- /* Map transform */
-
- for (i = 0; i < n; i++) geo_to_xy (x[i], y[i], &x[i], &y[i]);
-
- if (fp_d) {
- n_alloc = 3 * GMT_CHUNK;
- ind = (int *) memory (CNULL, n_alloc, sizeof (int), "pscontour");
-
- ij = np = 0;
-
- if (bin) /* Binary input */
- more = (fread ((char *)ind, sizeof (int), 3, fp_d) == 3);
- else /* ascii input */
- more = (fgets (line, 512, fp_d) != CNULL);
-
- while (more) {
- if (!bin && sscanf (line, "%d %d %d", &ind[ij], &ind[ij+1], &ind[ij+2]) != 3) continue;
- ij += 3;
- np++;
- if (ij == n_alloc) {
- n_alloc += (3 * GMT_CHUNK);
- ind = (int *) memory ((char *)ind, n_alloc, sizeof (int), "pscontour");
- }
- if (bin) /* Binary input */
- more = (fread ((char *)&ind[ij], sizeof (int), 3, fp_d) == 3);
- else /* ascii input */
- more = (fgets (line, 512, fp_d) != CNULL);
- }
- ind = (int *) memory ((char *)ind, ij, sizeof (int), "pscontour");
- fclose (fp_d);
- }
- else /* Do Delauney triangulation */
-
- np = delaunay (x, y, n, &ind);
-
- /* Get PSCONTOUR structs */
-
- n_contours = gmt_n_colors + 1;
- cont = (struct PSCONTOUR *) memory (CNULL, n_contours, sizeof (struct PSCONTOUR), "pscontour");
-
- for (i = 0; i < gmt_n_colors; i++) {
- cont[i].val = gmt_lut[i].z_low;
- cont[i].type = (gmt_lut[i].anot) ? 'A' : 'C';
- cont[i].angle = (fix_angle) ? label_angle : gmt_NaN;
- }
- cont[gmt_n_colors].val = gmt_lut[gmt_n_colors-1].z_high;
- cont[gmt_n_colors].type = (gmt_lut[gmt_n_colors-1].anot & 2) ? 'A' : 'C';
- cont[gmt_n_colors].angle = (fix_angle) ? label_angle : gmt_NaN;
- for (i = 0; i < n_contours; i++) {
- cont[i].n_alloc = GMT_SMALL_CHUNK;
- cont[i].L = (struct PSLINE *) memory (CNULL, GMT_SMALL_CHUNK, sizeof (struct PSLINE), "pscontour");
- }
-
- ps_setpaint (pen.r, pen.g, pen.b);
- ps_setline (pen.width);
- if (pen.texture) ps_setdash (pen.texture, pen.offset);
-
- for (i = ij = 0; i < np; i++, ij += 3) { /* For all triangles */
-
- k = ij;
- xx[0] = x[ind[k]]; yy[0] = y[ind[k]]; zz[0] = z[ind[k++]];
- xx[1] = x[ind[k]]; yy[1] = y[ind[k]]; zz[1] = z[ind[k++]];
- xx[2] = x[ind[k]]; yy[2] = y[ind[k]]; zz[2] = z[ind[k]];
-
- nx = get_triangle_crossings (x, y, z, &ind[ij], &xc, &yc, &zc, &vert, &cind);
-
- if (image_them) { /* Must color the triangle slices according to cpt file */
-
- /* First paint background color for entire triangle */
-
- z_min = MIN (zz[0], MIN (zz[1], zz[2]));
- get_rgb24 (z_min, &r, &g, &b);
- if (project_info.three_D) {
- for (k = 0; k < 3; k++) xy_do_z_to_xy (xx[k], yy[k], project_info.z_level, &xout[k], &yout[k]);
- ps_patch (xout, yout, 3, r, g, b, FALSE);
- }
- else
- ps_patch (xx, yy, 3, r, g, b, FALSE);
-
- /* Then loop over contours and paint the part that is higher up in the color scheme */
-
- for (k = k2 = 0, k3 = 1; k < nx; k++, k2 += 2, k3 += 2) {
- xout[0] = xc[k2]; yout[0] = yc[k2];
- xout[1] = xc[k3]; yout[1] = yc[k3];
- node = get_node_index (vert[k2], vert[k3]);
-
- /* We either add one vertix and paint that triangle or we must add the other
- two vertices and paint a polygon. The if-test will tell us which one */
-
- if (zz[node] > zc[k2]) { /* Add this single vertex to path */
- xout[2] = xx[node];
- yout[2] = yy[node];
- get_rgb24 (zc[k2], &r, &g, &b);
- if (project_info.three_D)
- for (kk = 0; kk < 3; kk++) xy_do_z_to_xy (xout[kk], yout[kk], project_info.z_level, &xout[kk], &yout[kk]);
- ps_patch (xout, yout, 3, r, g, b, FALSE);
- }
- else { /* Must add the other two vertices */
- n1 = (node + 1) % 3;
- n2 = (node + 2) % 3;
- way1 = get_direction (vert[k2], vert[k3]);
- way2 = get_direction (n1, n2);
- if (way1 * way2 < 0) i_swap (n1, n2);
- xout[2] = xx[n1]; yout[2] = yy[n1];
- xout[3] = xx[n2]; yout[3] = yy[n2];
- get_rgb24 (zc[k2], &r, &g, &b);
- if (project_info.three_D)
- for (kk = 0; kk < 4; kk++) xy_do_z_to_xy (xout[kk], yout[kk], project_info.z_level, &xout[kk], &yout[kk]);
- ps_patch (xout, yout, 4, r, g, b, FALSE);
- }
- }
- }
-
- if (draw_contours && nx > 0) { /* Save contour lines for later */
-
- if (project_info.three_D)
- for (k = 0; k < 2*nx; k++) xy_do_z_to_xy (xc[k], yc[k], project_info.z_level, &xc[k], &yc[k]);
-
- for (k = k2 = 0; k < nx; k++) {
- c = cind[k];
- n = cont[c].nl;
- cont[c].L[n].x0 = xc[k2];
- cont[c].L[n].y0 = yc[k2++];
- cont[c].L[n].x1 = xc[k2];
- cont[c].L[n].y1 = yc[k2++];
- n++;
- if (n >= cont[c].n_alloc) {
- cont[c].n_alloc += GMT_SMALL_CHUNK;
- cont[c].L = (struct PSLINE *) memory ((char *)cont[c].L, cont[c].n_alloc, sizeof (struct PSLINE), "pscontour");
- }
- cont[c].nl = n;
- }
-
- /* for (k = 0; k < nx; k++) ps_line (&xc[2*k], &yc[2*k], 2, 3, FALSE, FALSE); */
- }
-
- if (nx > 0) {
- free ((char *)xc);
- free ((char *)yc);
- free ((char *)zc);
- free ((char *)vert);
- free ((char *)cind);
- }
- }
-
- /* Draw contours */
-
- if (draw_contours) {
-
- struct CHAIN *head_c, *last_c, *this_c;
- struct PT *p, *q;
-
- anchor = old_label = (struct LABEL *) memory (CNULL, 1, sizeof (struct LABEL), "pscontour");
-
- for (c = 0; c < n_contours; c++) {
-
- if (cont[c].nl == 0) {
- free ((char *)cont[c].L);
- continue;
- }
-
- head_c = last_c = (struct CHAIN *) memory (CNULL, 1, sizeof (struct CHAIN), "pscontour");
-
- while (cont[c].nl) {
- this_c = last_c->next = (struct CHAIN *) memory (CNULL, 1, sizeof (struct CHAIN), "pscontour");
- k = 0;
- this_c->begin = (struct PT *) memory (CNULL, 1, sizeof (struct PT), "pscontour");
- this_c->end = (struct PT *) memory (CNULL, 1, sizeof (struct PT), "pscontour");
- this_c->begin->x = cont[c].L[k].x0;
- this_c->begin->y = cont[c].L[k].y0;
- this_c->end->x = cont[c].L[k].x1;
- this_c->end->y = cont[c].L[k].y1;
- this_c->begin->next = this_c->end;
- cont[c].nl--;
- cont[c].L[k] = cont[c].L[cont[c].nl];
- while (k < cont[c].nl) {
- add = 0;
- if (fabs(cont[c].L[k].x0 - this_c->begin->x) < SMALL && fabs(cont[c].L[k].y0 - this_c->begin->y) < SMALL) {
- p = (struct PT *) memory (CNULL, 1, sizeof (struct PT), "pscontour");
- p->x = cont[c].L[k].x1;
- p->y = cont[c].L[k].y1;
- p->next = this_c->begin;
- add = -1;
- }
- else if (fabs(cont[c].L[k].x1 - this_c->begin->x) < SMALL && fabs(cont[c].L[k].y1 - this_c->begin->y) < SMALL) {
- p = (struct PT *) memory (CNULL, 1, sizeof (struct PT), "pscontour");
- p->x = cont[c].L[k].x0;
- p->y = cont[c].L[k].y0;
- p->next = this_c->begin;
- add = -1;
- }
- else if (fabs(cont[c].L[k].x0 - this_c->end->x) < SMALL && fabs(cont[c].L[k].y0 - this_c->end->y) < SMALL) {
- p = (struct PT *) memory (CNULL, 1, sizeof (struct PT), "pscontour");
- p->x = cont[c].L[k].x1;
- p->y = cont[c].L[k].y1;
- this_c->end->next = p;
- add = 1;
- }
- else if (fabs(cont[c].L[k].x1 - this_c->end->x) < SMALL && fabs(cont[c].L[k].y1 - this_c->end->y) < SMALL) {
- p = (struct PT *) memory (CNULL, 1, sizeof (struct PT), "pscontour");
- p->x = cont[c].L[k].x0;
- p->y = cont[c].L[k].y0;
- this_c->end->next = p;
- add = 1;
- }
- if (add) { /* Got one */
- if (add == -1)
- this_c->begin = p;
- else if (add == 1)
- this_c->end = p;
- cont[c].nl--;
- cont[c].L[k] = cont[c].L[cont[c].nl];
- k = 0;
- }
- else
- k++;
- }
- last_c = this_c;
- }
- free ((char *)cont[c].L);
-
- this_c = head_c->next;
- while (this_c) {
- xp = (double *) memory (CNULL, GMT_SMALL_CHUNK, sizeof (double), "pscontour");
- yp = (double *) memory (CNULL, GMT_SMALL_CHUNK, sizeof (double), "pscontour");
- n_alloc = GMT_SMALL_CHUNK;
- p = this_c->begin;
- n = 0;
- while (p) {
- xp[n] = p->x;
- yp[n++] = p->y;
- q = p;
- p = p->next;
- free ((char *)q);
- if (n == n_alloc) {
- n_alloc += GMT_SMALL_CHUNK;
- xp = (double *) memory ((char *)xp, n_alloc, sizeof (double), "pscontour");
- yp = (double *) memory ((char *)yp, n_alloc, sizeof (double), "pscontour");
- }
- }
- last_c = this_c;
- this_c = this_c->next;
- free ((char *)last_c);
-
- close = (xp[0] == xp[n-1] && yp[0] == yp[n-1]);
- draw_contour (xp, yp, n, cont[c].val, cont[c].type, cont[c].angle, close, anot_dist);
- if (dump) dump_contour (xp, yp, n, cont[c].val, section++, close, dfile, &multi_segments, EOL_flag);
-
- free ((char *)xp);
- free ((char *)yp);
- }
-
- }
- plot_labels (label_font_size, box, br, bg, bb);
- }
-
- if (pen.texture) ps_setdash (CNULL, 0);
-
- if (clip) map_clip_off ();
-
- 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 (0, 0, 0);
-
- if (project_info.three_D) ps_rotatetrans (z_project.xmin, z_project.ymin, 0.0);
-
- ps_plotend (gmtdefs.last_page);
-
- free ((char *)x);
- free ((char *)y);
- free ((char *)z);
- free ((char *)ind);
-
- gmt_end (argc, argv);
- }
-
-
- int get_triangle_crossings (x, y, z, ind, xc, yc, zc, v, cindex)
- double x[], y[], z[];
- int ind[];
- double *xc[], *yc[], *zc[];
- int *v[], *cindex[]; {
- int i, j, k, k2, i1, nx, n_alloc, *vout, *cind;
- double xx[3], yy[3], zz[3], zmin, zmax, dz, frac, *xout, *yout, *zout;
-
- xx[0] = x[ind[0]]; yy[0] = y[ind[0]]; zz[0] = z[ind[0]];
- xx[1] = x[ind[1]]; yy[1] = y[ind[1]]; zz[1] = z[ind[1]];
- xx[2] = x[ind[2]]; yy[2] = y[ind[2]]; zz[2] = z[ind[2]];
-
- zmin = MIN (zz[0], MIN (zz[1], zz[2]));
- zmax = MAX (zz[0], MAX (zz[1], zz[2]));
-
- i = 0; j = gmt_n_colors - 1;
- while (gmt_lut[i].z_low <= zmin && i < gmt_n_colors) i++;
- while (gmt_lut[j].z_high >= zmax && j > 0) j--;
-
- nx = j - i + 2;
-
- if (nx == 0) return (0);
-
- n_alloc = 2 * nx;
- xout = (double *) memory (CNULL, n_alloc, sizeof (double), "pscontour");
- yout = (double *) memory (CNULL, n_alloc, sizeof (double), "pscontour");
- zout = (double *) memory (CNULL, n_alloc, sizeof (double), "pscontour");
- vout = (int *) memory (CNULL, n_alloc, sizeof (int), "pscontour");
- cind = (int *) memory (CNULL, nx, sizeof (int), "pscontour");
-
- k = k2 = 0;
- while (i <= j) {
- zout[k2] = zout[k2+1] = gmt_lut[i].z_low;
- cind[k++] = i;
- k2 += 2;
- i++;
- }
- zout[k2] = zout[k2+1] = gmt_lut[j].z_high;
- cind[k] = j + 1;
-
- for (k = k2 = j = 0; k < nx; k++, k2 += 2) {
- for (i = 0; i < 3; i++) {
- i1 = (i == 2) ? 0 : i + 1;
- if ((zout[k2] >= zz[i] && zout[k2] < zz[i1]) || (zout[k2] <= zz[i] && zout[k2] > zz[i1])) {
- dz = zz[i1] - zz[i];
- if (dz == 0.0) { /* Contour goes along ende */
- xout[j] = xx[i]; yout[j] = yy[i];
- }
- else {
- frac = (zout[k2] - zz[i]) / dz;
- xout[j] = xx[i] + frac * (xx[i1] - xx[i]);
- yout[j] = yy[i] + frac * (yy[i1] - yy[i]);
- }
- vout[j++] = i;
- }
- }
- if (j%2) j--; /* Contour went through a single vertice only, skip this */
- }
-
- *xc = xout;
- *yc = yout;
- *zc = zout;
- *v = vout;
- *cindex = cind;
-
- return (j/2);
- }
-
- int draw_contour (xx, yy, nn, cval, ctype, cangle, closed, gap)
- double *xx, *yy, cval, cangle, gap;
- char ctype;
- int nn, closed; {
- int i, j;
- double dist, angle, dx, dy, width, one = 1.0;
- char label[100], format[50];
- struct LABEL *new_label;
-
- if (nn < 2) return;
-
- sprintf (format, "%lg contour\0", cval);
- ps_comment (format);
-
- ps_line (xx, yy, nn, 3, closed, TRUE);
-
- if (ctype == 'A' || ctype == 'a') { /* Annotated contours */
- if (!gmtdefs.measure_unit) one = 2.5;
- get_format (cval, format);
- sprintf (label, format, cval);
- dist = (closed) ? gap - one : 0.0; /* Label closed contours longer than 1 inch */
- for (i = 1; i < nn; i++) {
-
- dx = xx[i] - xx[i-1];
- if (fabs (dx) > (width = gmt_half_map_width (yy[i-1]))) {
- width *= 2.0;
- dx = copysign (width - fabs (dx), -dx);
- if (xx[i] < width)
- xx[i-1] -= width;
- else
- xx[i-1] += width;
- }
- dy = yy[i] - yy[i-1];
- dist += hypot (dx, dy);
- if (dist > gap) { /* Time for label */
- new_label = (struct LABEL *) memory (CNULL, 1, sizeof (struct LABEL), "pscontour");
- new_label->x = 0.5 * (xx[i-1] + xx[i]);
- new_label->y = 0.5 * (yy[i-1] + yy[i]);
- strcpy (new_label->label, label);
- if (bad_float (cangle)) { /* Must calculate label angle */
- angle = d_atan2 (dy, dx) * R2D;
- if (angle < 0.0) angle += 360.0;
- if (angle > 90.0 && angle < 270) angle -= 180.0;
- }
- else
- angle = cangle;
- new_label->angle = angle;
- new_label->prev_label = old_label;
- dist = 0.0;
- old_label->next_label = new_label;
- old_label = new_label;
- }
- }
- }
- }
-
- int plot_labels (size, box, r, g, b)
- int size, box, r, g, b; {
- /* box = 1: white box only, box = 2: white box + draw outline */
- double dx, dy;
- struct LABEL *this, *old;
-
- dx = 0.5 * gmtdefs.anot_offset;
- dy = 0.05 * gmtdefs.anot_offset;
- box--;
- ps_comment ("Contour annotations:");
-
- ps_setpaint (gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
-
- for (old = anchor; old->next_label; old = old->next_label) { /* First draw boxes if not 3-D*/
- this = old->next_label;
- gmt_textbox3d (this->x, this->y, project_info.z_level, size, gmtdefs.anot_font, this->label, this->angle, 6, box, dx, dy, r, g, b);
- }
- for (old = anchor; old->next_label; old = old->next_label) { /* Then labels */
- this = old->next_label;
- gmt_text3d (this->x, this->y, project_info.z_level, size, gmtdefs.anot_font, this->label, this->angle, 6, 0);
- }
-
- ps_setpaint (gmtdefs.background_rgb[0], gmtdefs.background_rgb[1], gmtdefs.background_rgb[2]);
-
- this = anchor;
- while (this) { /* Free memory */
- old = this;
- this = old->next_label;
- free ((char *)old);
- }
- }
-
- int dump_contour (xx, yy, nn, cval, id, interior, file, m_segment, flag)
- double *xx, *yy, cval;
- char *file, flag;
- int nn, id;
- BOOLEAN interior, *m_segment; {
- int i;
- double lon, lat;
- char fname[512], format[80];
- FILE *fp;
-
- if (nn < 2) return;
-
- sprintf (format, "%s\t%s\t%s\n\0", gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format);
- if (*m_segment) {
- if (*m_segment == 2) { /* Must create file the first time around */
- fp = fopen (file, "w");
- *m_segment = TRUE;
- }
- else /* Later we append to it */
- fp = fopen (file, "a+");
- fprintf (fp, "%c %lg contour\n", flag, cval);
- }
- else {
- if (interior)
- sprintf (fname, "%s_%lg_%d_i.xyz\0", file, cval, id);
- else
- sprintf (fname, "%s_%lg_%d.xyz\0", file, cval, id);
- fp = fopen (fname, "w");
- }
- for (i = 0; i < nn; i++) {
- xy_to_geo (&lon, &lat, xx[i], yy[i]);
- fprintf (fp, format, lon, lat, cval);
- }
- fclose (fp);
- }
-
-