static void label_line(int n, double *xpts, double *ypts, double *zpts, char *label) { int i, j, k; int error_ind; int n_pts; double dist; double r_sqr; double a, b, c; double ox, oy; double dx, dy, t; double xtpt1, ytpt1, xtpt2, ytpt2; double cpx, cpy, tx[4], ty[4]; double x_up_val, y_up_val; double x_text_pos, y_text_pos; double d, e; /*-------------------------------------------------------------------------- / Find out how large the label is so we will know how much room to leave / for it. /-------------------------------------------------------------------------*/ x_up_val = 0.0; y_up_val = 1.0; gks_set_text_upvec(x_up_val, y_up_val); d = 0.0; e = 0.0; gks_select_xform(contour_vars.ndc); gks_inq_text_extent(contour_vars.wkid, d, e, label, &error_ind, &cpx, &cpy, tx, ty); gks_select_xform(contour_vars.tnr); a = (tx[2] - tx[0]) / contour_vars.scale_factor; b = (ty[2] - ty[0]) / contour_vars.scale_factor; r_sqr = (a * a + b * b) / 4.0; /* Gap in line reduced to half size */ /*-------------------------------------------------------------------------- / Try to find a good place to put the label on the contour line. /-------------------------------------------------------------------------*/ k = find_good_place(n, xpts, ypts, r_sqr); if (k != -1) { /*---------------------------------------------------------------------- / Find the first point outside of the circle centered at 'pts[k]' /---------------------------------------------------------------------*/ i = k; do { if (--i < 0) { i = n - 2; } dx = xpts[i] - xpts[k]; dy = (ypts[i] - ypts[k]) * contour_vars.aspect_ratio; dist = dx * dx + dy * dy; } while (dist < r_sqr); /*---------------------------------------------------------------------- / Find the intersection of line segment p[i]--p[i+1] with the circle /---------------------------------------------------------------------*/ dx = xpts[i + 1] - xpts[i]; dy = (ypts[i + 1] - ypts[i]) * contour_vars.aspect_ratio; ox = xpts[i] - xpts[k]; oy = (ypts[i] - ypts[k]) * contour_vars.aspect_ratio; a = dx * dx + dy * dy; b = ox * dx + oy * dy; c = ox * ox + oy * oy - r_sqr; t = -(b + sqrt(b * b - a * c)) / a; xtpt1 = xpts[i] + t * dx; ytpt1 = ypts[i] + t * (ypts[i + 1] - ypts[i]); /*---------------------------------------------------------------------- / Same as above but in the other direction /---------------------------------------------------------------------*/ j = k; do { if (++j >= n) { j = 1; } dx = xpts[j] - xpts[k]; dy = (ypts[j] - ypts[k]) * contour_vars.aspect_ratio; dist = dx * dx + dy * dy; } while (dist < r_sqr); /*---------------------------------------------------------------------- / Find the intersection of line segment p[j]--p[j-1] with the circle /---------------------------------------------------------------------*/ dx = xpts[j - 1] - xpts[j]; dy = (ypts[j - 1] - ypts[j]) * contour_vars.aspect_ratio; ox = xpts[j] - xpts[k]; oy = (ypts[j] - ypts[k]) * contour_vars.aspect_ratio; a = dx * dx + dy * dy; b = ox * dx + oy * dy; c = ox * ox + oy * oy - r_sqr; t = -(b + sqrt(b * b - a * c)) / a; xtpt2 = xpts[j] + t * dx; ytpt2 = ypts[j] + t * (ypts[j - 1] - ypts[j]); /*---------------------------------------------------------------------- / Calculate the character up vector. /---------------------------------------------------------------------*/ x_up_val = (ytpt1 - ytpt2) * contour_vars.aspect_ratio; y_up_val = xtpt2 - xtpt1; if (y_up_val < 0.0) { x_up_val = -x_up_val; y_up_val = -y_up_val; } gks_set_text_upvec(x_up_val, y_up_val); x_text_pos = (xpts[k] - contour_vars.wn[0]) * contour_vars.scale_factor + contour_vars.vp[0]; y_text_pos = (ypts[k] - contour_vars.wn[2]) * contour_vars.scale_factor * contour_vars.aspect_ratio + contour_vars.vp[2]; gks_select_xform(contour_vars.ndc); gks_text(x_text_pos, y_text_pos, label); gks_select_xform(contour_vars.tnr); /*---------------------------------------------------------------------/ / Draw the contour line leaving a gap for the text. /---------------------------------------------------------------------*/ if (i >= j) { xpts[i + 1] = xtpt1; ypts[i + 1] = ytpt1; xpts[j - 1] = xtpt2; ypts[j - 1] = ytpt2; /* zpts remain the same */ n_pts = i - j + 3; gr_polyline3d(n_pts, xpts + j - 1, ypts + j - 1, zpts + j - 1); } else { xpts[i + 1] = xtpt1; ypts[i + 1] = ytpt1; n_pts = i + 2; gr_polyline3d(n_pts, xpts, ypts, zpts); xpts[j - 1] = xtpt2; ypts[j - 1] = ytpt2; n_pts = n - j + 1; gr_polyline3d(n_pts, xpts + j - 1, ypts + j - 1, zpts + j - 1); } } else { n_pts = n; gr_polyline3d(n_pts, xpts, ypts, zpts); } }
static void draw(double x, double y, double z, int iflag) { static int n = 0; static double xpts[contour_max_pts]; static double ypts[contour_max_pts]; static double zpts[contour_max_pts]; static double line_length = 0; static int z_exept_flag = 0; double dx, dy; int linetype; char label[20]; switch (iflag % 10) { case 1: /* Continue polyline */ if (z_exept_flag == 0) { xpts[n] = x; ypts[n] = y; zpts[n] = z; if ((contour_vars.txtflg == 1) && ((contour_vars.lblmjh == 1) || (((iflag / 10 - 1) % contour_vars.lblmjh) == 1))) { dx = xpts[n] - xpts[n - 1]; dy = (ypts[n] - ypts[n - 1]) * contour_vars.aspect_ratio; line_length += contour_vars.scale_factor * sqrt(dx * dx + dy * dy); } n++; if ((line_length >= contour_max_length) || (n >= contour_max_pts)) { if ((contour_vars.txtflg == 1) && ((contour_vars.lblmjh == 1) || (((iflag / 10 - 1) % contour_vars.lblmjh) == 1))) { linetype = GKS_K_LINETYPE_SOLID; if (contour_vars.lblmjh > 1) { gks_set_pline_linetype(linetype); } sprintf(label, contour_vars.lblfmt, z); label_line(n, xpts, ypts, zpts, label); } else { if ((contour_vars.lblmjh <= 1) || (((iflag / 10 - 1) % contour_vars.lblmjh) == 1)) { linetype = GKS_K_LINETYPE_SOLID; } else { linetype = GKS_K_LINETYPE_DOTTED; } if (contour_vars.lblmjh > 1) { gks_set_pline_linetype(linetype); } gr_polyline3d(n, xpts, ypts, zpts); } xpts[0] = x; ypts[0] = y; zpts[0] = z; line_length = 0.0; n = 1; } } break; case 2: /* New polyline */ case 3: if ((z > contour_vars.zmin) && (z < contour_vars.zmax)) { z_exept_flag = 0; xpts[0] = x; ypts[0] = y; zpts[0] = z; line_length = 0.0; n = 1; } else z_exept_flag = 1; break; case 4: /* End polyline */ case 5: if (z_exept_flag == 0) { xpts[n] = x; ypts[n] = y; zpts[n] = z; if ((contour_vars.txtflg == 1) && ((contour_vars.lblmjh == 1) || (((iflag / 10 - 1) % contour_vars.lblmjh) == 1))) { dx = xpts[n] - xpts[n - 1]; dy = (ypts[n] - ypts[n - 1]) * contour_vars.aspect_ratio; line_length += contour_vars.scale_factor * sqrt(dx * dx + dy * dy); } n++; if ((line_length >= contour_min_length) && (contour_vars.txtflg == 1) && ((contour_vars.lblmjh == 1) || (((iflag / 10 - 1) % contour_vars.lblmjh) == 1))) { linetype = GKS_K_LINETYPE_SOLID; if (contour_vars.lblmjh > 1) { gks_set_pline_linetype(linetype); } sprintf(label, contour_vars.lblfmt, z); label_line(n, xpts, ypts, zpts, label); } else { if ((contour_vars.lblmjh <= 1) || (((iflag / 10 - 1) % contour_vars.lblmjh) == 1)) { linetype = GKS_K_LINETYPE_SOLID; } else { linetype = GKS_K_LINETYPE_DOTTED; } if (contour_vars.lblmjh > 1) { gks_set_pline_linetype(linetype); } gr_polyline3d(n, xpts, ypts, zpts); } } break; } }
void FORTRAN(gr_polyline3d)(int *n, double *px, double *py, double *pz) { gr_polyline3d(*n, px, py, pz); }