File: VClipPoly.c

package info (click to toggle)
acm 5.0-23.1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 8,364 kB
  • ctags: 4,793
  • sloc: ansic: 42,444; makefile: 706; cpp: 293; perl: 280; sh: 198
file content (142 lines) | stat: -rw-r--r-- 2,751 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#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;
}