home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)grdview.c 2.43 05 Jul 1995
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /*
- * grdview will read a topofile and produce a 3-D perspective plot
- * of the surface z = f(x,y) using PostScript. The surface can
- * be represented as:
- * 1) A Mesh plot
- * 2) A shaded (or colored) surface w/wo contourlines and w/wo
- * illumination by artificial sun(s).
- *
- * grdview calls contours to find the line segments that make up the
- * contour lines. This allows the user to specify that the contours
- * should be smoothed before plotting. This will make the resulting
- * image smoother, especially if nx and ny are relatively small.
- *
- * Author: Paul Wessel
- * Date: 8-DEC-1988
- * Modified: 5-JUL-1994 New version 3.0
- *
- */
-
- #include "gmt.h"
- #include "gmt_bcr.h"
-
- #define YIQ(r, g, b) rint (0.299 * (r) + 0.587 * (g) + 0.114 * (b)) /* How B/W TV's convert RGB to Gray */
-
- /* Declarations needed for binning of smooth contours */
-
- struct BIN {
- struct CONT *first_cont;
- } *binij;
-
- struct CONT {
- struct POINT *first_point;
- struct CONT *next_cont;
- double value;
- };
-
- struct POINT {
- double x, y;
- struct POINT *next_point;
- };
-
- /* Global variables */
-
- float *grd, *intensity, *topo;
-
- int *edge;
- int bin_inc[4], ij_inc[4];
- double x_inc[4], y_inc[4], *x, *y, *z, *v, *xx, *yy;
-
- char *c_method[3] = {
- "colorimage",
- "colortiles",
- "RGB-separation"
- };
-
- main (argc, argv)
- int argc;
- char **argv; {
- int i, j, ij, n_edges, k, n, max, i_bin, j_bin, i_bin_old, j_bin_old;
- int smooth = 1, side, way, nm, dummy[4], nx_f, ny_f, off, nx, ny;
- int red_facade = 0, green_facade = 0, blue_facade = 0, bin, two, mx, my;
- int c, r, g, b, i_start, i_stop, j_start, j_stop, i_inc, j_inc;
- int n_saddle, prev_side, entry, check, n_added, n_decimals = 3, dpi_i = 100;
- int sw, se, nw, ne, pad[4], index;
-
- BOOLEAN mesh = FALSE, draw_plane = FALSE, facade = FALSE, get_contours, bad;
- BOOLEAN error = FALSE, outline = FALSE, surface = FALSE, pen_not_set;
- BOOLEAN first, begin, draw_contours = FALSE, moved[4], intens = FALSE, drape = FALSE;
- BOOLEAN saddle, cross_ok, go, image = FALSE, monochrome = FALSE, simple_clip = TRUE;
-
- double cval, x_left, x_right, y_top, y_bottom, small, z_ave, this_intensity;
- double plane_level = 0.0, dx2, dy2, del_x, del_y, take_out, get_intensity();
- double west = 0.0, east = 0.0, south = 0.0, north = 0.0, new_z_level = 0.0, del_off;
- double data_west, data_east, data_south, data_north, delx, dely, z_val;
-
- float was[4];
-
- char *topofile, *intensfile, *drapefile, *cpt_file;
-
- struct CONT *get_cont_struct(), *start_cont, *this_cont, *last_cont;
- struct POINT *get_point(), *this_point, *last_point;
-
- struct GRD_HEADER header, t_head, i_head, d_head;
-
- struct PEN cpen, mpen;
- struct FILL fill;
-
- cpt_file = topofile = intensfile = drapefile = CNULL;
-
- argc = gmt_begin (argc, argv);
-
- gmt_init_pen (&mpen, 1);
- gmt_init_pen (&cpen, 3);
- gmt_init_fill (&fill, 255 - gmtdefs.basemap_frame_rgb[0], 255 - gmtdefs.basemap_frame_rgb[0], 255 - gmtdefs.basemap_frame_rgb[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 '\0':
- error += get_common_args (argv[i], &west, &east, &south, &north);
- break;
-
- /* Supplemental parameters */
-
- case 'C':
- cpt_file = &argv[i][2];
- break;
- case 'D':
- n_decimals = atoi (&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++;
- }
- break;
- case 'G':
- drapefile = &argv[i][2];
- drape = TRUE;
- break;
- case 'I':
- intensfile = &argv[i][2];
- intens = TRUE;
- break;
- case 'M':
- if (gmt_getpen (&argv[i][2], &mpen)) {
- gmt_pen_syntax ('M');
- error++;
- }
- break;
- case 'N':
- sscanf (&argv[i][2], "%lf/%d/%d/%d", &plane_level, &red_facade, &green_facade, &blue_facade);
- draw_plane = TRUE;
- if (strchr (&argv[i][2], '/')) facade = TRUE;
- if (check_rgb (red_facade, green_facade, blue_facade)) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR option -N: RGB components must all be in 0-255 range\n", gmt_program);
- error = TRUE;
- }
- break;
- case 'Q':
- switch (argv[i][2]) {
- case 'm': /* Mesh plot */
- mesh = TRUE;
- if (argv[i][3] == '/' && gmt_getfill (&argv[i][4], &fill)) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -Qm option: RGB components must all be in 0-255 range\n", gmt_program);
- error = TRUE;
- }
- break;
- case 's': /* Color wo/ contours */
- surface = TRUE;
- if (argv[i][3] == 'm') outline = TRUE;
- break;
- case 'I': /* image w/o simple clip*/
- simple_clip = FALSE;
- case 'i': /* image w/ simple clip*/
- image = TRUE;
- if (argv[i][3]) dpi_i = atoi (&argv[i][3]);
- break;
- default:
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Unrecognized qualifier (%c) for option -%c\n", gmt_program, argv[i][2], argv[i][1]);
- error = TRUE;
- break;
- }
- monochrome = (argv[i][strlen(argv[i])-1] == 'g');
- break;
- case 'S':
- smooth = atoi (&argv[i][2]);
- break;
- case 'W':
- if (gmt_getpen (&argv[i][2], &cpen)) {
- gmt_pen_syntax ('W');
- error++;
- }
- draw_contours = TRUE;
- break;
- case 'Z':
- new_z_level = atof (&argv[i][2]);
- break;
-
- /* Illegal options */
-
- default:
- error = TRUE;
- gmt_default_error (argv[i][1]);
- break;
- }
- }
- else
- topofile = argv[i];
- }
-
- if (!(mesh || surface || image)) mesh = TRUE; /* Default is mesh plot */
-
- if (argc == 1 || gmt_quick) {
- fprintf (stderr,"grdview %s - Plot topofiles in 3-D\n\n", GMT_VERSION);
- fprintf (stderr,"usage: grdview <topofile> -J<params> [-B<tickinfo>] [-C<cpt_file>] [-D<ndec>] [-E<v_az/v_el>]\n");
- fprintf (stderr," [-F<r/g/b>] [-G<drapefile>] [-I<intensfile>] [-K] [-M<pen>] [-N<level>] [-O] [-P]\n");
- fprintf (stderr," [-Q<type>] [-R<region>] [-S<smooth>] [-U] [-V] [-W<pen>]\n");
- fprintf (stderr," [-X<x_shift>] [-Y<y_shift>] [-Z<z_level>] [-c<ncopies>]\n\n");
-
- if (gmt_quick) exit (-1);
-
- fprintf (stderr," <topofile> is data set to be plotted\n");
- explain_option ('j');
- fprintf (stderr,"\n\tOPTIONS:\n");
- explain_option ('b');
- fprintf (stderr," -C Color palette file\n");
- fprintf (stderr," -D Number of decimals for color/gray specification in PostScript output [3]\n");
- fprintf (stderr," -E Draw perspective from viewpoint at azimuth <v_az>, elevation <v_el> (degrees).\n");
- fprintf (stderr," Default is looking straight down [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 <drapefile> rather than <topofile> is the data set to color-code.\n");
- fprintf (stderr," Use <topofile> as the relief and \'drape\' the image on top.\n");
- fprintf (stderr," Note that -Jz and -N always refers to the <topofile>\n");
- fprintf (stderr," -I gives name of intensity file and selects illumination\n");
- explain_option ('Z');
- explain_option ('K');
- fprintf (stderr," -M sets mesh pen attributes. [width = %d, color = (%d/%d/%d), solid line].\n",
- mpen.width, mpen.r, mpen.g, mpen.b);
- fprintf (stderr," -N<level> will draw a plane at z = level. Append color [/r/g/b] to paint\n");
- fprintf (stderr," the facade between the plane and the data perimeter.\n");
- explain_option ('O');
- explain_option ('P');
- fprintf (stderr," -Q sets plot reQuest. Choose one of the following:\n");
- fprintf (stderr," -Qm for Mesh plot [Default]. Append color for mesh paint [%d/%d/%d]\n", fill.r, fill.g, fill.b);
- fprintf (stderr," -Qs[m] for colored or shaded Surface. Append m to draw meshlines on the surface.\n");
- fprintf (stderr," -Qi for scanline converting polygons to rasterimage. Append effective dpi [100].\n");
- fprintf (stderr," -QI will Ignore clipping [Default will try to minimize damage to background by using naive clippath]\n");
- fprintf (stderr," To force a monochrome image using the YIQ transformation, append g\n");
- explain_option ('R');
- fprintf (stderr," -S will smooth contours first (see grdcontour for <smooth> value info).\n");
- explain_option ('U');
- explain_option ('V');
- fprintf (stderr," -W draw contours on top of surface or mesh. [Default is no contours]\n");
- fprintf (stderr, " Also sets contour line pen attributes [width = %d, color = (%d/%d/%d), solid line].\n",
- cpen.width, cpen.r, cpen.g, cpen.b);
- explain_option ('X');
- fprintf (stderr, " -Z For 3-D plots: Set the z-level of map [0]\n");
- explain_option ('c');
- explain_option ('.');
- exit (-1);
- }
-
- if (!topofile) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify input file\n", gmt_program);
- error++;
- }
- if (drape && !drapefile) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR option -G: Must specify drape file\n", gmt_program);
- error++;
- }
- if (intens && !intensfile) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR option -I: Must specify intensity file\n", gmt_program);
- error++;
- }
- if ((surface || image || draw_contours) && !cpt_file) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify color palette table\n", gmt_program);
- error++;
- }
- if (image && dpi_i <= 0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -Qi option: Must specify positive dpi\n", gmt_program);
- error++;
- }
- if (n_decimals < 1 || n_decimals > 3) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -D option: Enter number of decimals as 1, 2, or 3\n", gmt_program);
- error++;
- }
- if (smooth <= 0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -S option: smooth value must be positive\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 (error) exit (-1);
-
- if (cpt_file) {
- read_cpt (cpt_file);
- if (gmt_b_and_w) monochrome = TRUE;
- }
-
- get_contours = ( (mesh && draw_contours) || (surface && gmt_n_colors > 1) );
-
- two = (drape && get_contours) ? 2 : 0; /* Must read topofile with 2 boundary columns/rows */
-
- if (!strcmp (topofile, "=")) {
- fprintf (stderr, "grdview: Piping of topofile not supported!\n");
- exit (-1);
- }
-
- if (read_grd_info (topofile, &t_head)) {
- fprintf (stderr, "grdview: Error opening file %s\n", topofile);
- exit (-1);
- }
-
- if (intens && read_grd_info (intensfile, &i_head)) {
- fprintf (stderr, "grdview: Error opening file %s\n", intensfile);
- exit (-1);
- }
-
- if (drape && read_grd_info (drapefile, &d_head)) {
- fprintf (stderr, "grdview: Error opening file %s\n", drapefile);
- exit (-1);
- }
-
- off = (t_head.node_offset) ? 0 : 1;
- del_off = (t_head.node_offset) ? 0.5 : 0.0;
-
-
- /* Determine what wesn to pass to map_setup */
-
- if (west == east && south == north) {
- west = header.x_min;
- east = header.x_max;
- south = header.y_min;
- north = header.y_max;
- }
-
- map_setup (west, east, south, north);
-
- /* Determine the wesn to be used to read the grdfile */
-
- grd_setregion (&t_head, &data_west, &data_east, &data_south, &data_north);
-
- /* Read data */
-
- pad[0] = pad[1] = pad[2] = pad[3] = two;
- dummy[0] = dummy[1] = dummy[2] = dummy[3] = 0;
- nx = rint ( (data_east - data_west) / t_head.x_inc) + off;
- ny = rint ( (data_north - data_south) / t_head.y_inc) + off;
- mx = nx + 2 * two;
- my = ny + 2 * two;
- nm = nx * ny;
- topo = (float *) memory (CNULL, mx * my, sizeof (float), "grdview");
- if (read_grd (topofile, &t_head, topo, data_west, data_east, data_south, data_north, pad, FALSE)) {
- fprintf (stderr, "grdview: Error reading file %s\n", topofile);
- exit (-1);
- }
-
- nx_f = t_head.nx;
- ny_f = t_head.ny;
-
- if (gmtdefs.verbose) fprintf (stderr, "grdview: Processing topofile\n");
-
- delx = (t_head.node_offset) ? 0.5 * t_head.x_inc :0.0;
- dely = (t_head.node_offset) ? 0.5 * t_head.y_inc :0.0;
-
- if (drape) { /* draping wanted */
-
- if (d_head.nx != nx_f || d_head.ny != ny_f) {
- fprintf (stderr, "grdview: Drape file has improper dimensions!\n");
- exit (-1);
- }
- grd = (float *) memory (CNULL, nm, sizeof (float), "grdview");
- if (read_grd (drapefile, &d_head, grd, data_west, data_east, data_south, data_north, dummy, FALSE)) {
- fprintf (stderr, "grdview: Error reading file %s\n", drapefile);
- exit (-1);
- }
- header = d_head;
- }
- else {
- grd = topo;
- header = t_head;
- }
-
- if (project_info.z_bottom == 0.0 && project_info.z_top == 0.0) {
- project_info.z_bottom = t_head.z_min;
- project_info.z_top = t_head.z_max;
- if (draw_plane && plane_level < project_info.z_bottom) project_info.z_bottom = plane_level;
- if (draw_plane && plane_level > project_info.z_top) project_info.z_top = plane_level;
- }
-
- if (!project_info.xyz_pos[2]) /* Negative z-scale, must flip */
- d_swap (project_info.z_bottom, project_info.z_top);
-
- ij_inc[0] = 0; ij_inc[1] = 1; ij_inc[2] = 1 - mx; ij_inc[3] = -mx;
- bin_inc[0] = 0; bin_inc[1] = 1; bin_inc[2] = 1 - header.nx; bin_inc[3] = -header.nx;
- nw = two * mx + two;
- ne = nw + t_head.nx - 1;
- sw = (t_head.ny + two - 1) * mx + two;
- se = sw + t_head.nx - 1;
-
- init_setup (&t_head, topo, two, draw_plane, plane_level); /* Find projected min/max in y-direction */
-
- i_start = (z_project.quadrant == 1 || z_project.quadrant == 2) ? 0 : header.nx - 2;
- i_stop = (z_project.quadrant == 1 || z_project.quadrant == 2) ? header.nx - 1 : -1;
- i_inc = (z_project.quadrant == 1 || z_project.quadrant == 2) ? 1 : -1;
- j_start = (z_project.quadrant == 1 || z_project.quadrant == 4) ? header.ny - 1 : 1;
- j_stop = (z_project.quadrant == 1 || z_project.quadrant == 4) ? 0 : header.ny;
- j_inc = (z_project.quadrant == 1 || z_project.quadrant == 4) ? -1 : 1;
- x_inc[0] = x_inc[3] = 0.0; x_inc[1] = x_inc[2] = header.x_inc;
- y_inc[0] = y_inc[1] = 0.0; y_inc[2] = y_inc[3] = header.y_inc;
-
- if (get_contours) { /* Need to find contours */
- if (gmtdefs.verbose) fprintf (stderr, "grdview: Find contours\n");
- n_edges = header.ny * (int )ceil (header.nx / 16.0);
- edge = (int *) memory (CNULL, n_edges, sizeof (int), "grdview");
- binij = (struct BIN *) memory (CNULL, nm, sizeof (struct BIN), "grdview");
- small = SMALL * (header.z_max - header.z_min);
- if (gmtdefs.verbose) fprintf (stderr, "grdview: Trace and bin contours...\n");
- first = TRUE;
- for (c = 0; c < gmt_n_colors+1; c++) { /* For each color change */
-
- /* Reset markers and set up new zero-contour*/
-
- cval = (c == gmt_n_colors) ? gmt_lut[c-1].z_high : gmt_lut[c].z_low;
- if (gmtdefs.verbose) fprintf (stderr, "grdview: Now tracing contour interval %8lg\r", cval);
- take_out = (first) ? cval : cval - gmt_lut[c-1].z_low;
- first = FALSE;
- for (i = 0; i < nm; i++) {
- if (!bad_float ((double)grd[i])) grd[i] -= take_out;
- if (grd[i] == 0.0) grd[i] += small;
- }
-
- side = 0;
- begin = TRUE;
- while (side < 5) {
- while ((n = contours (grd, &header, smooth, gmtdefs.interpolant, &side, edge, begin, &x, &y)) > 0) {
-
- begin = FALSE;
-
- i_bin_old = j_bin_old = -1;
- for (i = 1; i < n; i++) {
- i_bin = floor (((0.5 * (x[i-1] + x[i]) - header.x_min) / header.x_inc) - del_off);
- j_bin = floor (((header.y_max - 0.5 * (y[i-1] + y[i])) / header.y_inc) - del_off) + 1;
- if (i_bin != i_bin_old || j_bin != j_bin_old) { /* Entering new bin */
- bin = j_bin * header.nx + i_bin;
- this_cont = get_cont_struct (bin, cval);
- this_cont->value = cval;
- this_cont->first_point = get_point (x[i-1], y[i-1]);
- this_point = this_cont->first_point;
- i_bin_old = i_bin;
- j_bin_old = j_bin;
- }
- this_point->next_point = get_point (x[i], y[i]);
- this_point = this_point->next_point;
- }
- free ((char *)x);
- free ((char *)y);
- }
- begin = FALSE;
- }
- }
-
- /* Remove temporary variables */
-
- free ((char*)edge);
-
- /* Go back to beginning and reread since grd has been destroyed */
-
- if (drape) {
- if (read_grd_info (drapefile, &d_head)) {
- fprintf (stderr, "grdview: Error opening file %s\n", drapefile);
- exit (-1);
- }
- if (read_grd (drapefile, &d_head, grd, data_west, data_east, data_south, data_north, dummy, FALSE)) {
- fprintf (stderr, "grdview: Error reading file %s\n", drapefile);
- exit (-1);
- }
- header = d_head;
- }
- else {
- if (read_grd_info (topofile, &t_head)) {
- fprintf (stderr, "grdview: Error opening file %s\n", topofile);
- exit (-1);
- }
- if (read_grd (topofile, &t_head, topo, data_west, data_east, data_south, data_north, pad, FALSE)) {
- fprintf (stderr, "grdview: Error reading file %s\n", topofile);
- exit (-1);
- }
- grd = topo;
- header = t_head;
- }
- if (gmtdefs.verbose) fprintf (stderr, "\n");
- }
-
- if (intens) { /* Illumination wanted */
-
- if (i_head.nx != nx_f || i_head.ny != ny_f) {
- fprintf (stderr, "grdview: Intensity file has improper dimensions!\n");
- exit (-1);
- }
- intensity = (float *) memory (CNULL, nm, sizeof (float), "grdview");
- if (read_grd (intensfile, &i_head, intensity, data_west, data_east, data_south, data_north, dummy, FALSE)) {
- fprintf (stderr, "grdview: Error reading file %s\n", intensfile);
- exit (-1);
- }
- }
-
- if (two) { /* Initialize bcr stuff */
- bcr_init (&t_head, pad, FALSE);
-
- /* Set boundary conditions */
-
- set_bcr_boundaries (&t_head, topo);
- }
-
- max = 2 * (smooth * (((header.nx > header.ny) ? header.nx : header.ny) + 2)) + 1;
- x = (double *) memory (CNULL, max, sizeof (double), "grdview");
- y = (double *) memory (CNULL, max, sizeof (double), "grdview");
- z = (double *) memory (CNULL, max, sizeof (double), "grdview");
- v = (double *) memory (CNULL, max, sizeof (double), "grdview");
-
- dx2 = 0.5 * header.x_inc; dy2 = 0.5 * header.y_inc;
-
- if (gmtdefs.verbose) fprintf (stderr, "grdview: Start creating PostScript plot\n");
-
- 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]));
-
- ps_setformat (n_decimals);
- 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 (new_z_level != 0.0) project_info.z_level = new_z_level;
-
- if (frame_info.plot && !image) { /* Plot basemap */
- frame_info.header[0] = 0; /* No header for grdview and psxyz */
- 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]);
- }
-
- max = 2 * (smooth * (((header.nx > header.ny) ? header.nx : header.ny) + 2)) + 1;
- xx = (double *) memory (CNULL, max, sizeof(double), "grdview");
- yy = (double *) memory (CNULL, max, sizeof(double), "grdview");
- if (draw_plane) {
- ps_comment ("Plot the plane at desired level");
- if (!z_project.draw[0]) { /* Southern side */
- for (i = 0; i < header.nx; i++) geoz_to_xy (header.x_min + i * header.x_inc + delx, header.y_min + dely, plane_level, &xx[i], &yy[i]);
- ps_line (xx, yy, header.nx, 3, TRUE, TRUE);
- }
- if (!z_project.draw[2]) { /* Northern side */
- for (i = 0; i < header.nx; i++) geoz_to_xy (header.x_min + i * header.x_inc + delx, header.y_max - dely, plane_level, &xx[i], &yy[i]);
- ps_line (xx, yy, header.nx, 3, TRUE, TRUE);
- }
- if (!z_project.draw[3]) { /* Western side */
- for (j = 0; j < header.ny; j++) geoz_to_xy (header.x_min + delx, header.y_max - j * header.y_inc - dely, plane_level, &xx[j], &yy[j]);
- ps_line (xx, yy, header.ny, 3, TRUE, TRUE);
- }
- if (!z_project.draw[1]) { /* Eastern side */
- for (j = 0; j < header.ny; j++) geoz_to_xy (header.x_max - delx, header.y_max - j * header.y_inc - dely, plane_level, &xx[j], &yy[j]);
- ps_line (xx, yy, header.ny, 3, TRUE, TRUE);
- }
-
- geoz_to_xy (header.x_min + delx, header.y_min + dely, plane_level, &xx[0], &yy[0]);
- geoz_to_xy (header.x_max - delx, header.y_min + dely, plane_level, &xx[1], &yy[1]);
- geoz_to_xy (header.x_max - delx, header.y_max - dely, plane_level, &xx[2], &yy[2]);
- geoz_to_xy (header.x_min + delx, header.y_max - dely, plane_level, &xx[3], &yy[3]);
- if (!bad_float ((double)topo[nw])) {
- geoz_to_xy (header.x_min + delx, header.y_max - dely, (double)(topo[nw]), &x_left, &y_top);
- ps_plot (x_left, y_top, 3); ps_plot (xx[3], yy[3], 2);
- }
- if (!bad_float ((double)topo[ne])) {
- geoz_to_xy (header.x_max - delx, header.y_max - dely, (double)(topo[ne]), &x_right, &y_top);
- ps_plot (x_right, y_top, 3); ps_plot (xx[2], yy[2], 2);
- }
- if (!bad_float ((double)topo[se])) {
- geoz_to_xy (header.x_max - delx, header.y_min + dely, (double)(topo[se]), &x_right, &y_bottom);
- ps_plot (x_right, y_bottom, 3); ps_plot (xx[1], yy[1], 2);
- }
- if (!bad_float ((double)topo[sw])) {
- geoz_to_xy (header.x_min + delx, header.y_min + dely, (double)(topo[sw]), &x_left, &y_bottom);
- ps_plot (x_left, y_bottom, 3); ps_plot (xx[0], yy[0], 2);
- }
- ps_plot (0.0, 0.0, 3); /* To make sure path is stroked */
- }
-
- if (image) { /* compute image */
- int nx_i, ny_i, kk, ip, jp, min_i, max_i, min_j, max_j, dist, node, nm_i, layers, *ix, *iy;
- BOOLEAN done;
- double *xval, *yval, xp, yp, sum_w, w, sum_i, x_width, y_width;
- double sum_r, sum_g, sum_b, intval;
- unsigned char *bitimage_24, *bitimage_8;
-
- if (gmtdefs.verbose) fprintf (stderr, "grdview: get and store projected vertices\n");
- ps_comment ("Plot 3-D surface using scanline conversion of polygons to raster image");
-
- x_width = z_project.xmax - z_project.xmin; /* Size of image in inches */
- y_width = z_project.ymax - z_project.ymin;
- nx_i = rint (x_width * dpi_i); /* Size of image in pixels */
- ny_i = rint (y_width * dpi_i);
-
- ix = (int *) memory (CNULL, nm, sizeof (int), "grdview");
- iy = (int *) memory (CNULL, nm, sizeof (int), "grdview");
-
- xval = (double *) memory (CNULL, header.nx, sizeof (double), "grdview");
- yval = (double *) memory (CNULL, header.ny, sizeof (double), "grdview");
- for (i = 0; i < header.nx; i++, bin++) xval[i] = header.x_min + i * header.x_inc;
- for (j = 0; j < header.ny; j++) yval[j] = header.y_max - j * header.y_inc;
-
- for (j = bin = ij = 0; j < header.ny; j++) { /* Get projected coordinates converted to pixel locations */
- ij = (two) ? (j + 2) * mx + two : bin;
- for (i = 0; i < header.nx; i++, bin++, ij++) {
- geoz_to_xy (xval[i], yval[j], (double)topo[ij], &xp, &yp);
- ix[bin] = floor ((xp - z_project.xmin) * dpi_i);
- iy[bin] = floor ((yp - z_project.ymin) * dpi_i);
- }
- }
- free ((char *) xval);
- free ((char *) yval);
-
- /* Allocate image array and set background to PAGE_COLOR */
-
- if (monochrome) {
- int gray;
-
- nm_i = nx_i * ny_i;
- layers = 1;
- bitimage_8 = (unsigned char *) memory (CNULL, nm_i, sizeof (char), "grdview");
- gray = YIQ (gmtdefs.page_rgb[0], gmtdefs.page_rgb[1], gmtdefs.page_rgb[2]);
- memset ((char *)bitimage_8, gray, nm_i);
- }
- else {
- nm_i = nx_i * ny_i * 3;
- layers = 3;
- bitimage_24 = (unsigned char *) memory (CNULL, nm_i, sizeof (char), "grdview");
- kk = 0;
- while (kk < nm_i) {
- bitimage_24[kk++] = gmtdefs.page_rgb[0];
- bitimage_24[kk++] = gmtdefs.page_rgb[1];
- bitimage_24[kk++] = gmtdefs.page_rgb[2];
- }
- }
-
- /* Plot from back to front */
-
- if (gmtdefs.verbose) fprintf (stderr, "grdview: Start rasterization\n");
- for (j = j_start; j != j_stop; j += j_inc) {
- #ifdef DEBUG
- fprintf (stderr, "grdview: Scan line conversion at j-line %.4d\r", j);
- #endif
- for (i = i_start; i != i_stop; i += i_inc) {
- bin = j * header.nx + i;
- ij = (two) ? (j + 2) * header.nx + i + 2 : bin;
- for (k = bad = 0; !bad && k < 4; k++) bad += bad_float ((double)topo[ij+ij_inc[k]]);
- if (bad) continue;
- min_i = MIN (ix[bin+bin_inc[0]], MIN (ix[bin+bin_inc[1]], MIN (ix[bin+bin_inc[2]], ix[bin+bin_inc[3]])));
- max_i = MAX (ix[bin+bin_inc[0]], MAX (ix[bin+bin_inc[1]], MAX (ix[bin+bin_inc[2]], ix[bin+bin_inc[3]])));
- min_j = MIN (iy[bin+bin_inc[0]], MIN (iy[bin+bin_inc[1]], MIN (iy[bin+bin_inc[2]], iy[bin+bin_inc[3]])));
- max_j = MAX (iy[bin+bin_inc[0]], MAX (iy[bin+bin_inc[1]], MAX (iy[bin+bin_inc[2]], iy[bin+bin_inc[3]])));
-
- for (jp = min_j; jp < max_j; jp++) {
- for (ip = min_i; ip < max_i; ip++) {
- if (!pixel_inside (ip, jp, ix, iy, bin)) continue;
- kk = layers * ((ny_i-jp-1) * nx_i + ip);
- sum_r = sum_g = sum_b = sum_w = sum_i = 0.0;
- done = FALSE;
- for (k = 0; !done && k < 4; k++) {
- node = bin + bin_inc[k];
- get_rgb24 (grd[node], &r, &g, &b);
- dist = idist (ip, jp, ix[node], iy[node]);
- if (dist == 0) { /* Only need this corner value */
- done = TRUE;
- if (intens) intval = intensity[node];
- }
- else {
- w = 1.0 / (double)dist;
- sum_r += r * w;
- sum_g += g * w;
- sum_b += b * w;
- if (intens) sum_i += intensity[node] * w;
- sum_w += w;
- }
- }
- if (!done) { /* Must get weighted value */
- sum_w = 1.0 / sum_w;
- r = rint (sum_r * sum_w);
- g = rint (sum_g * sum_w);
- b = rint (sum_b * sum_w);
- if (intens) intval = sum_i * sum_w;
- }
- if (intens) illuminate (intval, &r, &g, &b);
- if (monochrome) /* YIQ transformation */
- bitimage_8[kk] = (unsigned char) YIQ (r, g, b);
- else {
- bitimage_24[kk++] = r;
- bitimage_24[kk++] = g;
- bitimage_24[kk] = b;
- }
- }
- }
- }
- }
-
- if (!project_info.three_D)
- map_clip_on (-1, -1, -1, 3);
- else if (simple_clip) { /* Will attempt a simple clip path to minimize damage to background plots */
- int jm1, jp1;
-
- geoz_to_xy (header.x_min, header.y_min, project_info.z_bottom, &xx[0], &yy[0]);
- geoz_to_xy (header.x_max, header.y_min, project_info.z_bottom, &xx[1], &yy[1]);
- geoz_to_xy (header.x_max, header.y_max, project_info.z_bottom, &xx[2], &yy[2]);
- geoz_to_xy (header.x_min, header.y_max, project_info.z_bottom, &xx[3], &yy[3]);
-
- for (i = 1, j = 0; i < 4; i++) if (yy[i] > yy[j]) j = i;
- for (i = 3; i >= j+1; i--) xx[i+1] = xx[i], yy[i+1] = yy[i];
- jm1 = j - 1;
- if (jm1 < 0) jm1 += 5;
- jp1 = j + 1;
- if (jp1 > 3) jp1 -= 4;
- xx[j] = xx[jm1];
- yy[j] = z_project.ymax;
- xx[j+1] = xx[jp1];
- yy[j+1] = z_project.ymax;
- ps_clipon (xx, yy, 5, -1, -1, -1, 3);
- }
-
- if (gmtdefs.verbose) fprintf (stderr, "grdview: Creating PostScript image ");
- if (monochrome) {
- if (gmtdefs.verbose) fprintf (stderr, "[B/W image]\n");
- ps_image (z_project.xmin, z_project.ymin, x_width, y_width, bitimage_8, nx_i, ny_i, 8);
- free ((char *)bitimage_8);
- }
- else {
- if (gmtdefs.verbose) fprintf (stderr, "[%s]\n", c_method[gmtdefs.color_image]);
- if (gmtdefs.color_image == 2)
- fprintf (stderr, "%s: GMT Warning: PostScript output may only be processed with psto24!\n", gmt_program);
- color_image (z_project.xmin, z_project.ymin, x_width, y_width, bitimage_24, nx_i, ny_i);
- free ((char *)bitimage_24);
- }
- if (!project_info.three_D || simple_clip) ps_clipoff ();
-
- free ((char *)ix);
- free ((char *)iy);
- }
- if (mesh) {
- ps_comment ("Start of mesh plot");
- ps_setline (mpen.width);
- ps_setpaint (mpen.r, mpen.g, mpen.b);
- if (mpen.texture) ps_setdash (mpen.texture, mpen.offset);
- for (j = j_start; j != j_stop; j += j_inc) {
- y_bottom = header.y_max - j * header.y_inc - dely;
- y_top = y_bottom + abs (j_inc) * header.y_inc;
- for (i = i_start; i != i_stop; i += i_inc) {
- bin = j * header.nx + i;
- ij = (two) ? (j + 2) * mx + i + 2 : bin;
- for (k = bad = 0; !bad && k < 4; k++) bad += bad_float ((double)topo[ij+ij_inc[k]]);
- if (bad) continue;
- x_left = header.x_min + i * header.x_inc + delx;
- x_right = x_left + abs (i_inc) * header.x_inc;
- geoz_to_xy (x_left, y_bottom, (double)(topo[ij+ij_inc[0]]), &xx[0], &yy[0]);
- geoz_to_xy (x_right, y_bottom, (double)(topo[ij+ij_inc[1]]), &xx[1], &yy[1]);
- geoz_to_xy (x_right, y_top, (double)(topo[ij+ij_inc[2]]), &xx[2], &yy[2]);
- geoz_to_xy (x_left, y_top, (double)(topo[ij+ij_inc[3]]), &xx[3], &yy[3]);
- ps_patch (xx, yy, 4, fill.r, fill.g, fill.b, TRUE);
- if (draw_contours) {
- pen_not_set = TRUE;
- if (binij[bin].first_cont == NULL) continue;
- for (this_cont = binij[bin].first_cont->next_cont; this_cont; this_cont = this_cont->next_cont) {
- for (k = 0, this_point = this_cont->first_point; this_point; this_point = this_point->next_point, k++) {
- z_val = (drape) ? get_bcr_z (&t_head, (double)this_point->x, (double)this_point->y, topo) : this_cont->value;
- if (z_val < -5000.0)
- error++;
- geoz_to_xy ((double)this_point->x, (double)this_point->y, z_val, &xx[k], &yy[k]);
- }
- if (pen_not_set) {
- if (mpen.texture) ps_setdash (CNULL, 0);
- ps_setline (cpen.width);
- ps_setpaint (cpen.r, cpen.g, cpen.b);
- if (cpen.texture) ps_setdash (cpen.texture, cpen.offset);
- pen_not_set = FALSE;
- }
- ps_line (xx, yy, k, 3, FALSE, TRUE);
- }
- if (!pen_not_set) {
- if (cpen.texture) ps_setdash (CNULL, 0);
- ps_setline (mpen.width);
- ps_setpaint (mpen.r, mpen.g, mpen.b);
- if (mpen.texture) ps_setdash (mpen.texture, mpen.offset);
- }
- }
- }
- }
- if (mpen.texture) ps_setdash (CNULL, 0);
- }
- else if (surface) {
- ps_comment ("Start of filled surface");
- if (outline) {
- ps_setline (mpen.width);
- ps_setpaint (mpen.r, mpen.g, mpen.b);
- if (mpen.texture) ps_setdash (mpen.texture, mpen.offset);
- }
-
- for (j = j_start; j != j_stop; j += j_inc) {
- y_bottom = header.y_max - j * header.y_inc - dely;
- y_top = y_bottom + header.y_inc;
- for (i = i_start; i != i_stop; i += i_inc) {
- #ifdef DEBUG
- printf ("%% Doing bin (%d,%d)\n", i, j);
- #endif
- bin = j * header.nx + i;
- ij = (two) ? (j + 2) * mx + i + 2 : bin;
- for (k = bad = 0; !bad && k < 4; k++) bad += bad_float ((double)topo[ij+ij_inc[k]]);
- if (bad) continue;
- x_left = header.x_min + i * header.x_inc + delx;
- x_right = x_left + header.x_inc;
- if (intens) {
- this_intensity = get_intensity (intensity, bin, header.nx);
- if (bad_float (this_intensity)) continue;
- }
- if (get_contours && binij[bin].first_cont) { /* Contours go thru here */
- start_cont = binij[bin].first_cont->next_cont;
-
- /* Paint the part of the tile that has a value below the contour value */
-
- geoz_to_xy (x_left, y_bottom, (double)(topo[ij+ij_inc[0]]), &xx[0], &yy[0]);
- geoz_to_xy (x_right, y_bottom, (double)(topo[ij+ij_inc[1]]), &xx[1], &yy[1]);
- geoz_to_xy (x_right, y_top, (double)(topo[ij+ij_inc[2]]), &xx[2], &yy[2]);
- geoz_to_xy (x_left, y_top, (double)(topo[ij+ij_inc[3]]), &xx[3], &yy[3]);
-
- /* Set the right color */
-
- if (gmt_continuous) {
- z_ave = 0.0;
- for (n = k = 0; n < 4; n++) {
- if (grd[bin+bin_inc[n]] >= start_cont->value) continue;
- k++;
- z_ave += grd[bin+bin_inc[n]];
- }
- z_ave /= k;
- }
- else
- z_ave = start_cont->value - small;
-
- index = get_rgb24 (z_ave, &r, &g, &b);
- if (index >= 0 && !gmt_lut[index].skip) {
- if (intens ) illuminate (this_intensity, &r, &g, &b);
- ps_patch (xx, yy, 4, r, g, b, outline);
- }
-
- /* Now loop over all the contours that crossed this tile */
-
- saddle = FALSE;
- cross_ok = TRUE;
- n_saddle = 0;
-
- for (this_cont = start_cont; this_cont; this_cont = this_cont->next_cont) {
-
- /* First get all the x/y pairs for this contour */
-
- for (k = 0, this_point = this_cont->first_point; this_point; this_point = this_point->next_point, k++) {
- x[k] = this_point->x;
- y[k] = this_point->y;
- z[k] = (drape) ? get_bcr_z (&t_head, x[k], y[k], topo) : this_cont->value;
- v[k] = this_cont->value;
- }
-
- /* Check for saddle situation */
-
- if (!saddle && this_cont->next_cont && this_cont->next_cont->value == this_cont->value) saddle = TRUE;
- if (saddle) n_saddle++;
-
- /* First make sure no grd-value equals the contour value */
-
-
- for (side = 0; side < 4; side++) {
- if (grd[bin+bin_inc[side]] == this_cont->value) {
- was[side] = grd[bin+bin_inc[side]];
- grd[bin+bin_inc[side]] += small;
- moved[side] = TRUE;
- }
- else
- moved[side] = FALSE;
- }
-
- /* Then figure out on what side the contour exits */
-
- del_x = fabs (fmod (x[k-1] - header.x_min, header.x_inc));
- if (del_x > dx2) del_x = header.x_inc - del_x;
- del_y = fabs (fmod (y[k-1] - header.y_min, header.y_inc));
- if (del_y > dy2) del_y = header.y_inc - del_y;
- if (del_x < del_y) /* Cutting N-S gridlines */
- side = ((x[k-1]-x_left) > dx2) ? 1 : 3;
- else /* Cutting E-W gridlines */
- side = ((y[k-1]-y_bottom) > dy2) ? 2 : 0;
-
- /* If saddle, figure out on what side the contour enters */
-
- if (saddle && n_saddle == 1) {
- del_x = fabs (fmod (x[0] - header.x_min, header.x_inc));
- if (del_x > dx2) del_x = header.x_inc - del_x;
- del_y = fabs (fmod (y[0] - header.y_min, header.y_inc));
- if (del_y > dy2) del_y = header.y_inc - del_y;
- if (del_x < del_y) /* Cutting N-S gridlines */
- entry = ((x[0]-x_left) > dx2) ? 1 : 3;
- else /* Cutting E-W gridlines */
- entry = ((y[0]-y_bottom) > dy2) ? 2 : 0;
-
- if ((entry == 0 && side == 3) || (entry == 3 && side == 0))
- check = 0;
- else if ((entry == 1 && side == 2) || (entry == 2 && side == 1))
- check = 2;
- else if ((entry == 0 && side == 1) || (entry == 1 && side == 0))
- check = 1;
- else
- check = 3;
-
- cross_ok = (grd[bin+bin_inc[check]] < this_cont->value);
-
- }
-
- /* Now determine which way we have to go around the tile
- outline to close the polygon */
-
- way = (grd[bin+bin_inc[side]] >= this_cont->value) ? -1 : 1;
-
- /* Add the corner points that are needed to close the polygon */
-
- prev_side = side;
- if (way == 1) side++;
- for (n = n_added = 0; n < 4; n++) {
- side %= 4;
- if (cross_ok)
- go = TRUE;
- else if (n_added == 0)
- go = TRUE;
- else
- go = (side != (prev_side + 2)%4);
- if (go && grd[bin+bin_inc[side]] > this_cont->value) {
- x[k] = x_left + x_inc[side];
- y[k] = y_bottom + y_inc[side];
- z[k] = topo[ij+ij_inc[side]];
- v[k] = grd[bin+bin_inc[side]];
- k++;
- n_added++;
- prev_side = side;
- }
- side += way;
- if (side < 0) side += 4;
- }
-
- /* Compute the xy from the xyz triplets */
-
- for (n = 0; n < k; n++) geoz_to_xy (x[n], y[n], z[n], &xx[n], &yy[n]);
-
- if (gmt_continuous) {
- z_ave = 0.0;
- for (n = 0; n < k; n++) z_ave += v[n];
- z_ave /= k;
- }
- else
- z_ave = this_cont->value;
-
- /* Set the right color */
-
- get_rgb24 (z_ave+small, &r, &g, &b);
- if (intens) illuminate (this_intensity, &r, &g, &b);
-
- ps_patch (xx, yy, k, r, g, b, outline);
-
- /* Reset nodes that was moved off contour-value */
-
- for (side = 0; side < 4; side++) if (moved[side]) grd[bin+bin_inc[side]] = was[side];
-
- if (n_saddle == 2) {
- n_saddle = 0;
- saddle = FALSE;
- cross_ok = TRUE;
- }
- }
-
- /* Draw contour lines if desired */
-
- pen_not_set = TRUE;
- for (this_cont = start_cont; draw_contours && this_cont; this_cont = this_cont->next_cont) {
- for (k = 0, this_point = this_cont->first_point; this_point; this_point = this_point->next_point, k++) {
- z_val = (drape) ? get_bcr_z (&t_head, (double)this_point->x, (double)this_point->y, topo) : this_cont->value;
- geoz_to_xy ((double)this_point->x, (double)this_point->y, z_val, &xx[k], &yy[k]);
- }
- if (pen_not_set) {
- if (mpen.texture) ps_setdash (CNULL, 0);
- ps_setline (cpen.width);
- ps_setpaint (cpen.r, cpen.g, cpen.b);
- if (cpen.texture) ps_setdash (cpen.texture, cpen.offset);
- pen_not_set = FALSE;
- }
- ps_line (xx, yy, k, 3, FALSE, TRUE);
- }
- if (!pen_not_set) {
- if (cpen.texture) ps_setdash (CNULL, 0);
- ps_setline (mpen.width);
- ps_setpaint (mpen.r, mpen.g, mpen.b);
- if (mpen.texture) ps_setdash (mpen.texture, mpen.offset);
- }
- }
- else { /* No Contours, paint tile (any of the corner values will give correct color */
- geoz_to_xy (x_left, y_bottom, (double)(topo[ij]), &xx[0], &yy[0]);
- geoz_to_xy (x_right, y_bottom, (double)(topo[ij+ij_inc[1]]), &xx[1], &yy[1]);
- geoz_to_xy (x_right, y_top, (double)(topo[ij+ij_inc[2]]), &xx[2], &yy[2]);
- geoz_to_xy (x_left, y_top, (double)(topo[ij+ij_inc[3]]), &xx[3], &yy[3]);
-
- if (gmt_continuous) {
- for (n = 0, z_ave = 0.0; n < 4; n++) z_ave += grd[bin+bin_inc[n]];
- z_ave *= 0.25;
- }
- else
- z_ave = grd[bin];
- index = get_rgb24 (z_ave, &r, &g, &b);
- if (index >= 0 && !gmt_lut[index].skip) {
- if (intens ) illuminate (this_intensity, &r, &g, &b);
- ps_patch (xx, yy, 4, r, g, b, outline);
- }
- }
- }
- }
- }
- if (mpen.texture || cpen.texture) ps_setdash (CNULL, 0);
-
- if (project_info.three_D) { /* Redraw front axes */
- ps_setpaint (gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
- vertical_axis (2);
- ps_setpaint (gmtdefs.background_rgb[0], gmtdefs.background_rgb[1], gmtdefs.background_rgb[2]);
- }
-
- if (facade) { /* Cover the two front sides */
- ps_comment ("Paiting the frontal facade");
- ps_setline (1);
- if (!z_project.draw[0]) { /* Southern side */
- for (i = n = 0, ij = sw; i < header.nx; i++, ij++) {
- if (bad_float ((double)topo[ij])) continue;
- geoz_to_xy (header.x_min+i*header.x_inc+delx, header.y_min+dely, (double)(topo[ij]), &xx[n], &yy[n]);
- n++;
- }
- for (i = header.nx - 1; i >= 0; i--, n++) geoz_to_xy (header.x_min+i*header.x_inc+delx, header.y_min+dely, plane_level, &xx[n], &yy[n]);
- ps_polygon (xx, yy, n, red_facade, green_facade, blue_facade, TRUE);
- }
- if (!z_project.draw[1]) { /* Eastern side */
- for (j = n = 0, ij = ne; j < header.ny; j++, ij += mx) {
- if (bad_float ((double)topo[ij])) continue;
- geoz_to_xy (header.x_max-delx, header.y_max-j*header.y_inc-dely, (double)(topo[ij]), &xx[n], &yy[n]);
- n++;
- }
- for (j = header.ny - 1; j >= 0; j--, n++) geoz_to_xy (header.x_max-delx, header.y_max-j*header.y_inc-dely, plane_level, &xx[n], &yy[n]);
- ps_polygon (xx, yy, n, red_facade, green_facade, blue_facade, TRUE);
- }
- if (!z_project.draw[2]) { /* Northern side */
- for (i = n = 0, ij = nw; i < header.nx; i++, ij++) {
- if (bad_float ((double)topo[ij])) continue;
- geoz_to_xy (header.x_min+i*header.x_inc+delx, header.y_max-dely, (double)(topo[i]), &xx[n], &yy[n]);
- n++;
- }
- for (i = header.nx - 1; i >= 0; i--, n++) geoz_to_xy (header.x_min+i*header.x_inc+delx, header.y_max-dely, plane_level, &xx[n], &yy[n]);
- ps_polygon (xx, yy, n, red_facade, green_facade, blue_facade, TRUE);
- }
- if (!z_project.draw[3]) { /* Western side */
- for (j = n = 0, ij = nw; j < header.ny; j++, ij += mx) {
- if (bad_float ((double)topo[ij])) continue;
- geoz_to_xy (header.x_min+delx, header.y_max-j*header.y_inc-dely, (double)(topo[ij]), &xx[n], &yy[n]);
- n++;
- }
- for (j = header.ny - 1; j >= 0; j--, n++) geoz_to_xy (header.x_min+delx, header.y_max-j*header.y_inc-dely, plane_level, &xx[n], &yy[n]);
- ps_polygon (xx, yy, n, red_facade, green_facade, blue_facade, TRUE);
- }
- }
-
- if (project_info.three_D) ps_rotatetrans (z_project.xmin, z_project.ymin, 0.0);
-
- ps_plotend (gmtdefs.last_page);
-
- /* Free memory */
-
- if (get_contours) {
- for (ij = 0; ij < nm; ij++) {
- if (!binij[ij].first_cont) continue;
- last_cont = binij[ij].first_cont;
- for (this_cont = binij[ij].first_cont->next_cont; this_cont; this_cont = this_cont->next_cont) {
- if (this_cont->first_point) {
- last_point = this_cont->first_point;
- for (this_point = this_cont->first_point->next_point; this_point; this_point = this_point->next_point) {
- free ((char *)last_point);
- last_point = this_point;
- }
- free ((char *)last_point);
- }
- free ((char *)last_cont);
- last_cont = this_cont;
- }
- free ((char *)last_cont);
- }
- free ((char *)binij);
- }
-
- free ((char *)xx);
- free ((char *)yy);
- free ((char *)x);
- free ((char *)y);
- free ((char *)z);
- free ((char *)v);
- free ((char *)topo);
- if (intens) free ((char *)intensity);
- if (drape) free ((char *)grd);
-
- if (gmtdefs.verbose) fprintf (stderr, "grdview: Done!\n");
-
- gmt_end (argc, argv);
- }
-
- struct CONT *get_cont_struct (bin, value)
- int bin;
- double value; {
- struct CONT *cont, *new_cont;
-
- if (!binij[bin].first_cont) binij[bin].first_cont = (struct CONT *) memory (CNULL, 1, sizeof (struct CONT), "grdview");
-
- for (cont = binij[bin].first_cont; cont->next_cont && cont->next_cont->value <= value; cont = cont->next_cont);
-
- new_cont = (struct CONT *) memory (CNULL, 1, sizeof (struct CONT), "grdview");
- if (cont->next_cont) { /* Put it in the link */
- new_cont->next_cont = cont->next_cont;
- cont->next_cont = new_cont;
- }
- else /* End of list */
- cont->next_cont = new_cont;
- return (new_cont);
- }
-
- struct POINT *get_point (x, y)
- double x, y; {
- struct POINT *point;
-
- point = (struct POINT *) memory (CNULL, 1, sizeof (struct POINT), "grdview");
- point->x = x;
- point->y = y;
- return (point);
- }
-
- int init_setup (header, topo, two, draw_plane, plane_level)
- struct GRD_HEADER *header;
- float topo[];
- int two;
- BOOLEAN draw_plane;
- double plane_level; {
- int i, j, ij;
- double xtmp, ytmp, tmp, delx, dely;
-
- delx = (header->node_offset) ? 0.5 * header->x_inc :0.0;
- dely = (header->node_offset) ? 0.5 * header->y_inc :0.0;
- /* Find projected min/max in y-direction */
-
- z_project.ymax = z_project.ymin; /* Reset from whatever it was */
-
- for (j = 0; j < header->ny; j++) {
- ij = (j + two) * header->nx + two;
- for (i = 0; i < header->nx; i++, ij++) {
- if (bad_float ((double)topo[ij])) continue;
- geoz_to_xy (header->x_min + i * header->x_inc, header->y_max - j * header->y_inc, (double)topo[ij], &xtmp, &ytmp);
- z_project.ymin = MIN (z_project.ymin, ytmp);
- z_project.ymax = MAX (z_project.ymax, ytmp);
- }
- }
- if (draw_plane) { /* plane or facade may exceed the found min/max */
- for (i = 0; i < header->nx; i++) {
- tmp = header->x_min + i * header->x_inc + delx;
- geoz_to_xy (tmp, header->y_min + dely, plane_level, &xtmp, &ytmp);
- z_project.ymin = MIN (z_project.ymin, ytmp);
- z_project.ymax = MAX (z_project.ymax, ytmp);
- geoz_to_xy (tmp, header->y_max-dely, plane_level, &xtmp, &ytmp);
- z_project.ymin = MIN (z_project.ymin, ytmp);
- z_project.ymax = MAX (z_project.ymax, ytmp);
- }
- for (j = 0; j < header->ny; j++) {
- tmp = header->y_max - j * header->y_inc - dely;
- geoz_to_xy (header->x_min+delx, tmp, plane_level, &xtmp, &ytmp);
- z_project.ymin = MIN (z_project.ymin, ytmp);
- z_project.ymax = MAX (z_project.ymax, ytmp);
- geoz_to_xy (header->x_max-delx, tmp, plane_level, &xtmp, &ytmp);
- z_project.ymin = MIN (z_project.ymin, ytmp);
- z_project.ymax = MAX (z_project.ymax, ytmp);
- }
- }
- }
-
- double get_intensity (intensity, k, nx)
- float intensity[];
- int k, nx; {
- /* Finds the agerage intensity for this polygon */
- return (0.25 * (intensity[k] + intensity[k+1] + intensity[k-nx] + intensity[k-nx+1]));
- }
-
- int pixel_inside (ip, jp, ix, iy, bin)
- int ip, jp, ix[], iy[], bin; {
- int i, what;
- double x[6], y[6];
-
- for (i = 0; i < 4; i++) {
- x[i] = ix[bin+bin_inc[i]];
- y[i] = iy[bin+bin_inc[i]];
- }
- x[4] = x[0]; y[4] = y[0];
- what = non_zero_winding ((double)ip, (double)jp, x, y, 5);
- return (what);
- /* return (inside ((double)ip, (double)jp, x, y, 4)); */
- }
-
- int idist (x1, y1, x2, y2)
- int x1, y1, x2, y2; {
- if ((x2 -= x1) < 0) x2 = -x2;
- if ((y2 -= y1) < 0) y2 = -y2;
- return (x2 + y2 - (((x2 > y2) ? y2 : x2) >> 1));
- }
-