コード例 #1
0
ファイル: contour.c プロジェクト: vleo/gr
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);
    }
}
コード例 #2
0
ファイル: contour.c プロジェクト: vleo/gr
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;
    }
}
コード例 #3
0
ファイル: grforbnd.c プロジェクト: albertocabello/gr
void FORTRAN(gr_polyline3d)(int *n, double *px, double *py, double *pz)
{
  gr_polyline3d(*n, px, py, pz);
}