#include "Vlib.h" VPolygon * _VClipPolygon(VPolygon * poly, VPoint * clipPlane) { register int j, lastj, numPts = 0, clipped = 0; double d1, d2, a; VPoint tmpPoint[VmaxVP]; VPolygon *p; if (poly->numVtces > 0) { lastj = poly->numVtces - 1; d1 = VDotProd(&(poly->vertex[poly->numVtces - 1]), clipPlane); numPts = 0; /* * Examine each vertex and determine if it is inside or outside of the * specified clipping plane. */ for (j = 0; j < poly->numVtces; ++j) { /* Leading vertex inside? */ if (d1 > 0.0) tmpPoint[numPts++] = poly->vertex[lastj]; d2 = VDotProd(&(poly->vertex[j]), clipPlane); /* Does the edge straddle the window? If so, add a vertex on the window */ if (d1 * d2 < 0.0) { clipped = 1; a = d1 / (d1 - d2); tmpPoint[numPts].x = a * poly->vertex[j].x + (1.0 - a) * poly->vertex[lastj].x; tmpPoint[numPts].y = a * poly->vertex[j].y + (1.0 - a) * poly->vertex[lastj].y; tmpPoint[numPts++].z = a * poly->vertex[j].z + (1.0 - a) * poly->vertex[lastj].z; } lastj = j; d1 = d2; } } /* * If the polygon was completely out of bounds, delete this polygon. */ if (numPts == 0) { p = (VPolygon *) NULL; VDestroyPolygon(poly); #ifdef DEBUG fprintf(stderr, "VClipPolygon: polygon outside area of interest\n"); #endif } /* * If we did any clipping, return the clipped polygon. */ else if (clipped) { p = VCreatePolygonFromTemplate(numPts, tmpPoint, poly); #ifdef DEBUG fprintf(stderr, "VClipPolygon: Polygon has been clipped:\n"); fprintf(stderr, "Before Clipping:\n"); VPrintPolygon(stderr, poly); fprintf(stderr, "\nAfter Clipping:\n\n"); VPrintPolygon(stderr, p); #endif VDestroyPolygon(poly); } else p = poly; return p; } VPolygon * VClipPolygon(VPolygon * poly, VPolygon * clipPoly) { int i; VPolygon *p = poly; /* * Clip against each clipping plane supplied, one at a time. */ for (i = 0; i < clipPoly->numVtces; ++i) { if (p == (VPolygon *) NULL) break; p = _VClipPolygon(p, &(clipPoly->vertex[i])); } return p; } VPolygon * /*ARGSUSED */ VClipSidedPolygon(Viewport * v, VPolygon * poly, VPolygon * clipPoly) { int i; VPolygon *p = poly; if (p->flags & PolyNormalValid) { if (VDotProd(&p->vertex[0], &p->normal) >= 0.0) { if (p->backColor) { p->flags |= PolyUseBackColor; } else if (p->flags & PolyClipBackface) { VDestroyPolygon(p); return (VPolygon *) NULL; } } else { p->flags &= ~(PolyUseBackColor); } } /* * Clip against each clipping plane supplied, one at a time. */ for (i = 0; i < clipPoly->numVtces; ++i) { if (p == (VPolygon *) NULL) break; p = _VClipPolygon(p, &(clipPoly->vertex[i])); } return p; }