void
c_plfill3(PLINT n, PLFLT *x, PLFLT *y, PLFLT *z)
{
    PLFLT tx[PL_MAXPOLY], ty[PL_MAXPOLY], tz[PL_MAXPOLY];
    PLFLT *V[3];
    PLINT xpoly[PL_MAXPOLY], ypoly[PL_MAXPOLY];
    PLINT i;
    PLFLT xmin, xmax, ymin, ymax, zmin, zmax, zscale;

    if (plsc->level < 3) {
	plabort("plfill3: Please set up window first");
	return;
    }
    if (n < 3) {
	plabort("plfill3: Not enough points in object");
	return;
    }
    if (n > PL_MAXPOLY-1) {
	plwarn("plfill3: too many points in polygon");
	n = PL_MAXPOLY;
    }

    plP_gdom(&xmin, &xmax, &ymin, &ymax);
    plP_grange(&zscale, &zmin, &zmax);
    
    /* copy the vertices so we can clip without corrupting the input */
    for( i=0; i < n; i++ ) {
      tx[i] = x[i]; ty[i] = y[i]; tz[i] = z[i];
    }
    if (tx[0] != tx[n-1] || ty[0] != ty[n-1] || tz[0] != tz[n-1]) {
      tx[n] = tx[0]; ty[n] = ty[0]; tz[n] = tz[0];
      n++;
    }
    V[0] = tx; V[1] = ty; V[2] = tz;
    n = plP_clip_poly(n, V, 0,  1, -xmin);
    n = plP_clip_poly(n, V, 0, -1,  xmax);
    n = plP_clip_poly(n, V, 1,  1, -ymin);
    n = plP_clip_poly(n, V, 1, -1,  ymax);
    n = plP_clip_poly(n, V, 2,  1, -zmin);
    n = plP_clip_poly(n, V, 2, -1,  zmax);
    for( i=0; i < n; i++ ) {
	xpoly[i] = plP_wcpcx(plP_w3wcx( tx[i], ty[i], tz[i] ));
	ypoly[i] = plP_wcpcy(plP_w3wcy( tx[i], ty[i], tz[i] ));
	}

/* AWI: in the past we have used
 *  plP_fill(xpoly, ypoly, n);
 * here, but our educated guess is this fill should be done via the clipping
 * interface instead as below.
 * No example tests this code so one of our users will end up inadvertently
 * testing this for us. 
 *
 * jc: I have checked, and both versions does give the same result, i.e., clipping
 * to the window boundaries. The reason is that the above plP_clip_poly() does
 * the clipping. To check this, is enough to diminish the x/y/z min/max arguments in
 * plw3d() in x08c. But let's keep it, although 10% slower...
 */
    plP_plfclp(xpoly, ypoly, n, plsc->clpxmi, plsc->clpxma,
           plsc->clpymi, plsc->clpyma, plP_fill);
}
Example #2
0
void
c_plpoly3(PLINT n, PLFLT *x, PLFLT *y, PLFLT *z, PLBOOL *draw, PLBOOL ifcc)
{
    int i;
    PLFLT vmin[3], vmax[3], zscale;
    PLFLT u1, v1, u2, v2, u3, v3;
    PLFLT c;

    if (plsc->level < 3) {
	plabort("plpoly3: Please set up window first");
	return;
    }

    if ( n < 3 ) {
	plabort("plpoly3: Must specify at least 3 points");
	return;
    }

/* Now figure out which side this is. */

    u1 = plP_wcpcx(plP_w3wcx( x[0], y[0], z[0] ));
    v1 = plP_wcpcy(plP_w3wcy( x[0], y[0], z[0] ));

    u2 = plP_wcpcx(plP_w3wcx( x[1], y[1], z[1] ));
    v2 = plP_wcpcy(plP_w3wcy( x[1], y[1], z[1] ));

    u3 = plP_wcpcx(plP_w3wcx( x[2], y[2], z[2] ));
    v3 = plP_wcpcy(plP_w3wcy( x[2], y[2], z[2] ));

    c = (u1-u2)*(v3-v2)-(v1-v2)*(u3-u2);

    if ( c *(1 - 2*ABS(ifcc)) < 0. )
        return;

    /* get the bounding box in 3d */
    plP_gdom(&vmin[0], &vmax[0], &vmin[1], &vmax[1]);
    plP_grange(&zscale, &vmin[2], &vmax[2]);

    /* interate over the vertices */
    for( i=0; i < n-1; i++ ) {
      PLFLT p0[3], p1[3];
      int axis;

      /* copy the end points of the segment to allow clipping */
      p0[0] = x[i]; p0[1] = y[i]; p0[2] = z[i];
      p1[0] = x[i+1]; p1[1] = y[i+1]; p1[2] = z[i+1];

      /* check against each axis of the bounding box */
      for(axis = 0; axis < 3; axis++) {
	if(p0[axis] < vmin[axis]) { /* first out */
	  if(p1[axis] < vmin[axis]) {
	    break; /* both endpoints out so quit */
	  } else {
	    int j;
	    /* interpolate to find intersection with box */
	    PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]);
	    p0[axis] = vmin[axis];
	    for(j = 1; j<3; j++) {
	      int k = (axis+j)%3;
	      p0[k] = (1-t)*p0[k] + t*p1[k];
	    }
	  }
	} else if(p1[axis] < vmin[axis]) { /* second out */
	  int j;
	  /* interpolate to find intersection with box */
	  PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]);
	  p1[axis] = vmin[axis];
	  for(j = 1; j<3; j++) {
	    int k = (axis+j)%3;
	    p1[k] = (1-t)*p0[k] + t*p1[k];
	  }
	}
	if(p0[axis] > vmax[axis]) { /* first out */
	  if(p1[axis] > vmax[axis]) {
	    break; /* both out so quit */
	  } else {
	    int j;
	    /* interpolate to find intersection with box */
	    PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]);
	    p0[axis] = vmax[axis];
	    for(j = 1; j<3; j++) {
	      int k = (axis+j)%3;
	      p0[k] = (1-t)*p0[k] + t*p1[k];
	    }
	  }
	} else if(p1[axis] > vmax[axis]) { /* second out */
	  int j;
	  /* interpolate to find intersection with box */
	  PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]);
	  p1[axis] = vmax[axis];
	  for(j = 1; j<3; j++) {
	    int k = (axis+j)%3;
	    p1[k] = (1-t)*p0[k] + t*p1[k];
	  }
	}
      }
      /* if we made it to here without "break"ing out of the loop, the
	 remaining segment is visible */
      if( axis == 3 && draw[i] ) { /*  not clipped away */
	PLFLT myu0, myv0, myu1, myv1;
	myu0 = plP_wcpcx(plP_w3wcx( p0[0], p0[1], p0[2] ));
	myv0 = plP_wcpcy(plP_w3wcy( p0[0], p0[1], p0[2] ));
	myu1 = plP_wcpcx(plP_w3wcx( p1[0], p1[1], p1[2] ));
	myv1 = plP_wcpcy(plP_w3wcy( p1[0], p1[1], p1[2] ));
	plP_movphy(myu0,myv0);
	plP_draphy(myu1,myv1);
      }
    }
    return;
}
Example #3
0
/*----------------------------------------------------------------------*\
 * void plline3(n, x, y, z)
 *
 * Draws a line in 3 space.  You must first set up the viewport, the
 * 2d viewing window (in world coordinates), and the 3d normalized
 * coordinate box.  See x18c.c for more info.
 *
 * This version adds clipping against the 3d bounding box specified in plw3d
\*----------------------------------------------------------------------*/
void
c_plline3(PLINT n, PLFLT *x, PLFLT *y, PLFLT *z)
{
    int i;
    PLFLT vmin[3], vmax[3], zscale;

    if (plsc->level < 3) {
	plabort("plline3: Please set up window first");
	return;
    }

    /* get the bounding box in 3d */
    plP_gdom(&vmin[0], &vmax[0], &vmin[1], &vmax[1]);
    plP_grange(&zscale, &vmin[2], &vmax[2]);

    /* interate over the vertices */
    for( i=0; i < n-1; i++ ) {
      PLFLT p0[3], p1[3];
      int axis;

      /* copy the end points of the segment to allow clipping */
      p0[0] = x[i]; p0[1] = y[i]; p0[2] = z[i];
      p1[0] = x[i+1]; p1[1] = y[i+1]; p1[2] = z[i+1];

      /* check against each axis of the bounding box */
      for(axis = 0; axis < 3; axis++) {
	if(p0[axis] < vmin[axis]) { /* first out */
	  if(p1[axis] < vmin[axis]) {
	    break; /* both endpoints out so quit */
	  } else {
	    int j;
	    /* interpolate to find intersection with box */
	    PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]);
	    p0[axis] = vmin[axis];
	    for(j = 1; j<3; j++) {
	      int k = (axis+j)%3;
	      p0[k] = (1-t)*p0[k] + t*p1[k];
	    }
	  }
	} else if(p1[axis] < vmin[axis]) { /* second out */
	  int j;
	  /* interpolate to find intersection with box */
	  PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]);
	  p1[axis] = vmin[axis];
	  for(j = 1; j<3; j++) {
	    int k = (axis+j)%3;
	    p1[k] = (1-t)*p0[k] + t*p1[k];
	  }
	}
	if(p0[axis] > vmax[axis]) { /* first out */
	  if(p1[axis] > vmax[axis]) {
	    break; /* both out so quit */
	  } else {
	    int j;
	    /* interpolate to find intersection with box */
	    PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]);
	    p0[axis] = vmax[axis];
	    for(j = 1; j<3; j++) {
	      int k = (axis+j)%3;
	      p0[k] = (1-t)*p0[k] + t*p1[k];
	    }
	  }
	} else if(p1[axis] > vmax[axis]) { /* second out */
	  int j;
	  /* interpolate to find intersection with box */
	  PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]);
	  p1[axis] = vmax[axis];
	  for(j = 1; j<3; j++) {
	    int k = (axis+j)%3;
	    p1[k] = (1-t)*p0[k] + t*p1[k];
	  }
	}
      }
      /* if we made it to here without "break"ing out of the loop, the
	 remaining segment is visible */
      if( axis == 3 ) { /*  not clipped away */
	PLFLT u0, v0, u1, v1;
	u0 = plP_wcpcx(plP_w3wcx( p0[0], p0[1], p0[2] ));
	v0 = plP_wcpcy(plP_w3wcy( p0[0], p0[1], p0[2] ));
	u1 = plP_wcpcx(plP_w3wcx( p1[0], p1[1], p1[2] ));
	v1 = plP_wcpcy(plP_w3wcy( p1[0], p1[1], p1[2] ));
	plP_movphy(u0,v0);
	plP_draphy(u1,v1);
      }
    }
    return;
}
Example #4
0
MZ_DLLEXPORT
void
c_plbox3(const char *xopt, const char *xlabel, PLFLT xtick, PLINT nsubx,
	 const char *yopt, const char *ylabel, PLFLT ytick, PLINT nsuby,
	 const char *zopt, const char *zlabel, PLFLT ztick, PLINT nsubz)
{
    PLFLT dx, dy, tx, ty, ux, uy;
    PLFLT xmin, xmax, ymin, ymax, zmin, zmax, zscale;
    PLFLT cxx, cxy, cyx, cyy, cyz;
    PLINT ln;
    PLINT *zbflg, *zbcol;
    PLFLT *zbtck;
    PLINT xdigmax, xdigits;
    PLINT ydigmax, ydigits;
    PLINT zdigmax, zdigits;

    if (plsc->level < 3) {
	plabort("plbox3: Please set up window first");
	return;
    }

    plP_gw3wc(&cxx, &cxy, &cyx, &cyy, &cyz);
    plP_gdom(&xmin, &xmax, &ymin, &ymax);
    plP_grange(&zscale, &zmin, &zmax);

    plgxax(&xdigmax, &xdigits);
    plgyax(&ydigmax, &ydigits);
    plgzax(&zdigmax, &zdigits);

    xdigits = xdigmax;
    ydigits = ydigmax;
    zdigits = zdigmax;

/* We have to wait until after the plot is drawn to draw back */
/* grid so store this stuff. */

    plP_gzback(&zbflg, &zbcol, &zbtck);
    *zbflg = plP_stsearch(zopt, 'd');
    if (*zbflg) {
	*zbtck = ztick;		/* save tick spacing */
	*zbcol = plsc->icol0;	/* and color */
    }

    if (cxx >= 0.0 && cxy <= 0.0) {
	ln = plP_stsearch(xopt, 'n');
	tx = plP_w3wcx(xmin, ymin, zmin);
	ty = plP_w3wcy(xmin, ymin, zmin);
	ux = plP_w3wcx(xmax, ymin, zmin);
	uy = plP_w3wcy(xmax, ymin, zmin);
	plxybx(xopt, xlabel, tx, ty, ux, uy,
	       xmin, xmax, xtick, nsubx, 0, &xdigits);

	dx = ux - tx;
	dy = uy - ty;
	plzbx(zopt, zlabel, 1, dx, dy, ux, uy,
	      plP_w3wcy(xmax, ymin, zmax), zmin, zmax, ztick, nsubz, &zdigits);

	tx = plP_w3wcx(xmin, ymax, zmin);
	ty = plP_w3wcy(xmin, ymax, zmin);
	ux = plP_w3wcx(xmin, ymin, zmin);
	uy = plP_w3wcy(xmin, ymin, zmin);
	plxybx(yopt, ylabel, tx, ty, ux, uy,
	       ymax, ymin, ytick, nsuby, ln, &ydigits);

	dx = ux - tx;
	dy = uy - ty;
/* restore zdigits to initial value for second call */
        zdigits = zdigmax;     
	plzbx(zopt, zlabel, 0, dx, dy, tx, ty,
	      plP_w3wcy(xmin, ymax, zmax), zmin, zmax, ztick, nsubz, &zdigits);
    }
    else if (cxx <= 0.0 && cxy <= 0.0) {
	ln = plP_stsearch(yopt, 'n');
	tx = plP_w3wcx(xmin, ymax, zmin);
	ty = plP_w3wcy(xmin, ymax, zmin);
	ux = plP_w3wcx(xmin, ymin, zmin);
	uy = plP_w3wcy(xmin, ymin, zmin);
	plxybx(yopt, ylabel, tx, ty, ux, uy,
	       ymax, ymin, ytick, nsuby, 0, &ydigits);

	dx = ux - tx;
	dy = uy - ty;
	plzbx(zopt, zlabel, 1, dx, dy, ux, uy,
	      plP_w3wcy(xmin, ymin, zmax), zmin, zmax, ztick, nsubz, &zdigits);

	tx = plP_w3wcx(xmax, ymax, zmin);
	ty = plP_w3wcy(xmax, ymax, zmin);
	ux = plP_w3wcx(xmin, ymax, zmin);
	uy = plP_w3wcy(xmin, ymax, zmin);
	plxybx(xopt, xlabel, tx, ty, ux, uy,
	       xmax, xmin, xtick, nsubx, ln, &xdigits);

	dx = ux - tx;
	dy = uy - ty;
/* restore zdigits to initial value for second call */
        zdigits = zdigmax;     
	plzbx(zopt, zlabel, 0, dx, dy, tx, ty,
	      plP_w3wcy(xmax, ymax, zmax), zmin, zmax, ztick, nsubz, &zdigits);
    }
    else if (cxx <= 0.0 && cxy >= 0.0) {
	ln = plP_stsearch(xopt, 'n');
	tx = plP_w3wcx(xmax, ymax, zmin);
	ty = plP_w3wcy(xmax, ymax, zmin);
	ux = plP_w3wcx(xmin, ymax, zmin);
	uy = plP_w3wcy(xmin, ymax, zmin);
	plxybx(xopt, xlabel, tx, ty, ux, uy,
	       xmax, xmin, xtick, nsubx, 0, &xdigits);

	dx = ux - tx;
	dy = uy - ty;
	plzbx(zopt, zlabel, 1, dx, dy, ux, uy,
	      plP_w3wcy(xmin, ymax, zmax), zmin, zmax, ztick, nsubz, &zdigits);

	tx = plP_w3wcx(xmax, ymin, zmin);
	ty = plP_w3wcy(xmax, ymin, zmin);
	ux = plP_w3wcx(xmax, ymax, zmin);
	uy = plP_w3wcy(xmax, ymax, zmin);
	plxybx(yopt, ylabel, tx, ty, ux, uy,
	       ymin, ymax, ytick, nsuby, ln, &ydigits);

	dx = ux - tx;
	dy = uy - ty;
/* restore zdigits to initial value for second call */
        zdigits = zdigmax;     
	plzbx(zopt, zlabel, 0, dx, dy, tx, ty,
	      plP_w3wcy(xmax, ymin, zmax), zmin, zmax, ztick, nsubz, &zdigits);
    }
    else if (cxx >= 0.0 && cxy >= 0.0) {
	ln = plP_stsearch(yopt, 'n');
	tx = plP_w3wcx(xmax, ymin, zmin);
	ty = plP_w3wcy(xmax, ymin, zmin);
	ux = plP_w3wcx(xmax, ymax, zmin);
	uy = plP_w3wcy(xmax, ymax, zmin);
	plxybx(yopt, ylabel, tx, ty, ux, uy,
	       ymin, ymax, ytick, nsuby, 0, &ydigits);

	dx = ux - tx;
	dy = uy - ty;
	plzbx(zopt, zlabel, 1, dx, dy, ux, uy,
	      plP_w3wcy(xmax, ymax, zmax), zmin, zmax, ztick, nsubz, &zdigits);

	tx = plP_w3wcx(xmin, ymin, zmin);
	ty = plP_w3wcy(xmin, ymin, zmin);
	ux = plP_w3wcx(xmax, ymin, zmin);
	uy = plP_w3wcy(xmax, ymin, zmin);
	plxybx(xopt, xlabel, tx, ty, ux, uy,
	       xmin, xmax, xtick, nsubx, ln, &xdigits);

	dx = ux - tx;
	dy = uy - ty;
/* restore zdigits to initial value for second call */
        zdigits = zdigmax;     
	plzbx(zopt, zlabel, 0, dx, dy, tx, ty,
	      plP_w3wcy(xmin, ymin, zmax), zmin, zmax, ztick, nsubz, &zdigits);
    }
    plsxax(xdigmax, xdigits);
    plsyax(ydigmax, ydigits);
    plszax(zdigmax, zdigits);
}