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); }
void c_plpoin3(PLINT n, PLFLT *x, PLFLT *y, PLFLT *z, PLINT code) { PLINT i, sym, ifont = plsc->cfont; PLFLT u, v; PLFLT xmin, xmax, ymin, ymax, zmin, zmax, zscale; if (plsc->level < 3) { plabort("plpoin3: Please set up window first"); return; } if (code < -1 || code > 127) { plabort("plpoin3: Invalid code"); return; } plP_gdom(&xmin, &xmax, &ymin, &ymax); plP_grange(&zscale, &zmin, &zmax); if (code == -1) { for (i = 0; i < n; i++) { if(x[i] >= xmin && x[i] <= xmax && y[i] >= ymin && y[i] <= ymax && z[i] >= zmin && z[i] <= zmax) { u = plP_wcpcx(plP_w3wcx( x[i], y[i], z[i] )); v = plP_wcpcy(plP_w3wcy( x[i], y[i], z[i] )); plP_movphy(u,v); plP_draphy(u,v); } } } else { if (ifont > numberfonts) ifont = 1; sym = *(fntlkup + (ifont - 1) * numberchars + code); for( i=0; i < n; i++ ) { if(x[i] >= xmin && x[i] <= xmax && y[i] >= ymin && y[i] <= ymax && z[i] >= zmin && z[i] <= zmax) { u = plP_wcpcx(plP_w3wcx( x[i], y[i], z[i] )); v = plP_wcpcy(plP_w3wcy( x[i], y[i], z[i] )); plhrsh(sym, u, v); } } } return; }
/*----------------------------------------------------------------------*\ * 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; }
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; }
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); }