1*18196Sjaap #ifndef lint
2*18196Sjaap static char *sccsid ="opaque.c	(CWI)	1.1	85/03/01";
3*18196Sjaap #endif
4*18196Sjaap #include "ideal.h"
5*18196Sjaap #include "y.tab.h"
6*18196Sjaap 
opqact(opqstmt,noadtree,linelist)7*18196Sjaap LINEPTR opqact (opqstmt, noadtree, linelist)
8*18196Sjaap STMTPTR opqstmt;
9*18196Sjaap NOADPTR noadtree;
10*18196Sjaap LINEPTR linelist;
11*18196Sjaap {
12*18196Sjaap 	STMTPTR bdstmt;
13*18196Sjaap 	LINEPTR inlines, outlines, both;
14*18196Sjaap 	LINENODE nuline;
15*18196Sjaap 	LINEPTR prevline;
16*18196Sjaap 
17*18196Sjaap 	if (when_bug & 0100) bug_on;
18*18196Sjaap 	prevline = &nuline;
19*18196Sjaap 	prevline->next = NULL;
20*18196Sjaap 	both = linelist;
21*18196Sjaap 	if ((bdstmt = nextstmt (BDLIST, noadtree->defnode->parm->stmtlist))
22*18196Sjaap 		|| (bdstmt = nextstmt (BDLIST,findbox (noadtree->defnode->parm->name,FALSE)->stmtlist))) {
23*18196Sjaap 		EDGENODE edgelist;
24*18196Sjaap 		EXPRPTR bdwalk, lastbd;
25*18196Sjaap 		INTLPTR prevtx, curvtx, postvtx;
26*18196Sjaap 		EDGEPTR edgewalk;
27*18196Sjaap 		EDGEPTR forfreeing;
28*18196Sjaap 		lastbd = (EXPRPTR) tail ((BOXPTR) bdstmt->stmt);
29*18196Sjaap 		lastbd->next = exprgen (((EXPRPTR) bdstmt->stmt)->expr);
30*18196Sjaap 		edgewalk = &edgelist;
31*18196Sjaap 		prevtx = expreval (((EXPRPTR) bdstmt->stmt)->expr, noadtree);
32*18196Sjaap 		for (bdwalk = ((EXPRPTR) bdstmt->stmt)->next;
33*18196Sjaap 			bdwalk;
34*18196Sjaap 			bdwalk = bdwalk->next) {
35*18196Sjaap 			curvtx = expreval (bdwalk->expr, noadtree);
36*18196Sjaap 			if (((INTLPTR) bdwalk->expr)->oper == '^') {
37*18196Sjaap 				bdwalk = bdwalk->next;
38*18196Sjaap 				if (!bdwalk) {
39*18196Sjaap 					fprintf (stderr, "ideal: arc point may not begin boundary specification\n");
40*18196Sjaap 					return (linelist);
41*18196Sjaap 				}
42*18196Sjaap 				postvtx = expreval (bdwalk->expr, noadtree);
43*18196Sjaap 				edgewalk->next = edgearc (
44*18196Sjaap 					Re(prevtx),
45*18196Sjaap 					Im(prevtx),
46*18196Sjaap 					Re(curvtx),
47*18196Sjaap 					Im(curvtx),
48*18196Sjaap 					Re(postvtx),
49*18196Sjaap 					Im(postvtx)
50*18196Sjaap 				);
51*18196Sjaap 			} else {
52*18196Sjaap 				postvtx = curvtx;
53*18196Sjaap 				edgewalk->next = edgeline (
54*18196Sjaap 					Re(prevtx),
55*18196Sjaap 					Im(prevtx),
56*18196Sjaap 					Re(postvtx),
57*18196Sjaap 					Im(postvtx)
58*18196Sjaap 				);
59*18196Sjaap 			}
60*18196Sjaap 			prevtx = postvtx;
61*18196Sjaap 			edgewalk = edgewalk->next;
62*18196Sjaap 		}
63*18196Sjaap 		edgewalk->next = edgelist.next;
64*18196Sjaap 		lastbd->next = NULL;
65*18196Sjaap 		opqpoly (
66*18196Sjaap 			edgelist.next->next,
67*18196Sjaap 			linelist,
68*18196Sjaap 			&inlines,
69*18196Sjaap 			&outlines,
70*18196Sjaap 			&both
71*18196Sjaap 		);
72*18196Sjaap 		forfreeing = edgelist.next->next;
73*18196Sjaap 		edgelist.next->next = NULL;
74*18196Sjaap 		linefree (forfreeing);
75*18196Sjaap /*
76*18196Sjaap 	} else if (noadtree->defnode->parm->name == lookup ("circle")
77*18196Sjaap 		|| noadtree->defnode->parm->name == lookup ("hole")) {
78*18196Sjaap 		z0 = varfind (lookup ("center"), noadtree);
79*18196Sjaap 		r = varfind (lookup ("radius"), noadtree);
80*18196Sjaap 		if (!known (z0) || !known (r)) {
81*18196Sjaap 			fprintf (stderr, "ideal: indeterminate opaque circle\n");
82*18196Sjaap 			return (linelist);
83*18196Sjaap 		}
84*18196Sjaap 		opqcirc (
85*18196Sjaap 			Re(z0), Im(z0), Re(r),
86*18196Sjaap 			linelist,
87*18196Sjaap 			&inlines,
88*18196Sjaap 			&outlines,
89*18196Sjaap 			&both
90*18196Sjaap 		);
91*18196Sjaap 		intlfree (z0);
92*18196Sjaap 		intlfree (r);
93*18196Sjaap 	} else if (noadtree->defnode->parm->name == lookup ("sector")) {
94*18196Sjaap 		z0 = varfind (lookup ("center"), noadtree);
95*18196Sjaap 		r = varfind (lookup ("radius"), noadtree);
96*18196Sjaap 		z1 = varfind (lookup("start"), noadtree);
97*18196Sjaap 		z2 = varfind (lookup ("end"), noadtree);
98*18196Sjaap 		t1 = varfind (lookup ("startang"), noadtree);
99*18196Sjaap 		t2 = varfind (lookup ("endang"), noadtree);
100*18196Sjaap 		if (!known(z0) || !known(r) || !known(z1) || !known(z2)) {
101*18196Sjaap 			fprintf (stderr, "ideal: intederminate opaque sector\n");
102*18196Sjaap 				return (linelist);
103*18196Sjaap 		}
104*18196Sjaap 		opqsect (
105*18196Sjaap 			Re(z0), Im(z0), Re(r),
106*18196Sjaap 			Re(z1), Im(z1),
107*18196Sjaap 			Re(z2), Im(z2),
108*18196Sjaap 			Re(t1), Re(t2),
109*18196Sjaap 			linelist,
110*18196Sjaap 			&inlines,
111*18196Sjaap 			&outlines,
112*18196Sjaap 			&both
113*18196Sjaap 		);
114*18196Sjaap 		intlfree (z0);
115*18196Sjaap 		intlfree (r);
116*18196Sjaap 		intlfree (z1);
117*18196Sjaap 		intlfree (z2);
118*18196Sjaap 		intlfree (t1);
119*18196Sjaap 		intlfree (t2);
120*18196Sjaap 	} else if (noadtree->defnode->parm->name == lookup ("segment")) {
121*18196Sjaap 		z0 = varfind (lookup ("center"), noadtree);
122*18196Sjaap 		r = varfind (lookup ("radius"), noadtree);
123*18196Sjaap 		z1 = varfind (lookup ("start"), noadtree);
124*18196Sjaap 		z2 = varfind (lookup ("end"), noadtree);
125*18196Sjaap 		if (!known(z0) || !known(r) || !known(z1) || !known(z2)) {
126*18196Sjaap 			fprintf (stderr, "ideal: indeterminate opaque segment\n");
127*18196Sjaap 			return (linelist);
128*18196Sjaap 		}
129*18196Sjaap 		opqseg (
130*18196Sjaap 			Re(z0), Im(z0), Re(r),
131*18196Sjaap 			Re(z1), Im(z1),
132*18196Sjaap 			Re(z2), Im(z2),
133*18196Sjaap 			linelist,
134*18196Sjaap 			&inlines,
135*18196Sjaap 			&outlines,
136*18196Sjaap 			&both
137*18196Sjaap 		);
138*18196Sjaap 		intlfree (z0);
139*18196Sjaap 		intlfree (r);
140*18196Sjaap 		intlfree (z1);
141*18196Sjaap 		intlfree (z2);
142*18196Sjaap */
143*18196Sjaap 	} else {
144*18196Sjaap 		fprintf(stderr, "ideal: no boundary list\n");
145*18196Sjaap 	}
146*18196Sjaap 	if (((MISCPTR) opqstmt->stmt)->info == INTERIOR) {
147*18196Sjaap 		prevline->next = outlines;
148*18196Sjaap 		linefree (inlines);
149*18196Sjaap 	} else {
150*18196Sjaap 		prevline->next = inlines;
151*18196Sjaap 		linefree (outlines);
152*18196Sjaap 	}
153*18196Sjaap 	if (both) {
154*18196Sjaap 		while (prevline->next)
155*18196Sjaap 			prevline = prevline->next;
156*18196Sjaap 		prevline->next = both;
157*18196Sjaap 	}
158*18196Sjaap 	linelist = lineclean (nuline.next);
159*18196Sjaap 	bug_off;
160*18196Sjaap 	return (linelist);
161*18196Sjaap } /* opqact */
162*18196Sjaap 
opqinsert(code,alpha,opqlist)163*18196Sjaap void opqinsert (code, alpha, opqlist)
164*18196Sjaap int code;
165*18196Sjaap float alpha;
166*18196Sjaap OPQPTR *opqlist;
167*18196Sjaap {
168*18196Sjaap 	OPQNODE head;
169*18196Sjaap 	OPQPTR walk, prev, new;
170*18196Sjaap 	walk = &head;
171*18196Sjaap 	walk->alpha = -INFINITY;
172*18196Sjaap 	walk->next = *opqlist;
173*18196Sjaap 	prev = NULL;
174*18196Sjaap 	while (walk->next && walk->next->alpha < alpha + EPSILON) {
175*18196Sjaap 		prev = walk;
176*18196Sjaap 		walk = walk->next;
177*18196Sjaap 	}
178*18196Sjaap 	if (walk->alpha < alpha - EPSILON) {
179*18196Sjaap 		new = opqgen(code, alpha);
180*18196Sjaap 		new->next = walk->next;
181*18196Sjaap 		walk->next = new;
182*18196Sjaap 	} else {
183*18196Sjaap 		if (walk->code == EXT0 || walk->code == INFL0)
184*18196Sjaap 			if (code == EXT1 || code == INFL1) {
185*18196Sjaap 				walk->code = IGNORE;
186*18196Sjaap 			}
187*18196Sjaap 		else if (walk->code == EXT1 || walk->code == INFL1)
188*18196Sjaap 			if (code == EXT0 || code == INFL0) {
189*18196Sjaap 				walk->code = IGNORE;
190*18196Sjaap 			}
191*18196Sjaap 		else if (walk->code == SIMPLE && code != INHERIT)
192*18196Sjaap 			walk->code = code;
193*18196Sjaap 	}
194*18196Sjaap 	*opqlist = head.next;
195*18196Sjaap }
196*18196Sjaap 
lineclean(linelist)197*18196Sjaap LINEPTR lineclean (linelist)
198*18196Sjaap LINEPTR linelist;
199*18196Sjaap {
200*18196Sjaap 	/* clean short lines from linelist */
201*18196Sjaap 	LINEPTR prevline, linewalk;
202*18196Sjaap 	LINENODE nuhead;
203*18196Sjaap 	prevline = &nuhead;
204*18196Sjaap 	prevline->next = linewalk = linelist;
205*18196Sjaap 	while (linewalk) {
206*18196Sjaap 		if ((linewalk->kind == LINE)
207*18196Sjaap 			&& (fabs(linewalk->x0 - linewalk->x1) < EPSILON)
208*18196Sjaap 			&& (fabs(linewalk->y0 - linewalk->y1) < EPSILON)) {
209*18196Sjaap 			dprintf "Removing chopped line\n");
210*18196Sjaap 			prevline->next = linewalk->next;
211*18196Sjaap 			tryfree(linewalk);
212*18196Sjaap 			linewalk = prevline->next;
213*18196Sjaap 		} else {
214*18196Sjaap 			prevline = linewalk;
215*18196Sjaap 			linewalk = linewalk->next;
216*18196Sjaap 		}
217*18196Sjaap 	}
218*18196Sjaap 	linelist = nuhead.next;
219*18196Sjaap 	return (linelist);
220*18196Sjaap }
221*18196Sjaap 
222*18196Sjaap /*
223*18196Sjaap /*void tangent (x, y, dx, dy, x1, y1, x2, y2)
224*18196Sjaap /*float x, y, dx, dy;
225*18196Sjaap /*float *x1, *y1, *x2, *y2;
226*18196Sjaap /*{
227*18196Sjaap /*	*x1 = x + dx;
228*18196Sjaap /*	*x2 = x - dx;
229*18196Sjaap /*	*y1 = y + dy;
230*18196Sjaap /*	*y2 = y - dy;
231*18196Sjaap /*}
232*18196Sjaap */
233*18196Sjaap 
234*18196Sjaap /*
235*18196Sjaap /*void halfplane (x1,y1, x2,y2, linelist, inlines, outlines, both)
236*18196Sjaap /*float x1, y1, x2, y2;
237*18196Sjaap /*LINEPTR linelist;
238*18196Sjaap /*LINEPTR *inlines, *outlines, *both;
239*18196Sjaap /*{
240*18196Sjaap /*	LINEPTR edges;
241*18196Sjaap /*	float perpx, perpy;
242*18196Sjaap /*	float ulx, uly, urx, ury, llx, lly, lrx, lry;
243*18196Sjaap /*	dprintf "halfplane (%f,%f) (%f,%f)\n", x1, y1, x2, y2);
244*18196Sjaap /*	perpx = 10.0*(y1 - y2)/hypot ((x2 - x1), (y2 - y1));
245*18196Sjaap /*	perpy = 10.0*(x2 - x1)/hypot ((x2 - x1), (y2 - y1));
246*18196Sjaap /*	lrx = x1 - 10.0*(x2 - x1);
247*18196Sjaap /*	lry = y1 - 10.0*(y2 - y1);
248*18196Sjaap /*	urx = x1 + 10.0*(x2 - x1);
249*18196Sjaap /*	ury = y1 + 10.0*(y2 - y1);
250*18196Sjaap /*	ulx = urx + perpx;
251*18196Sjaap /*	uly = ury + perpy;
252*18196Sjaap /*	llx = lrx + perpx;
253*18196Sjaap /*	lly = lry + perpy;
254*18196Sjaap /*	dprintf "perpx %f perpy %f\n", perpx, perpy);
255*18196Sjaap /*	if (dbg)
256*18196Sjaap /*		fprintf (stderr, "(%f,%f)\n (%f,%f)\n (%f,%f)\n (%f,%f)\n",
257*18196Sjaap /*			lrx, lry,
258*18196Sjaap /*			urx, ury,
259*18196Sjaap /*			ulx, uly,
260*18196Sjaap /*			llx, lly
261*18196Sjaap /*		);
262*18196Sjaap /*	edges = linegen (lrx, lry, urx, ury);
263*18196Sjaap /*	edges->next = linegen (urx, ury, ulx, uly);
264*18196Sjaap /*	edges->next->next = linegen (ulx, uly, llx, lly);
265*18196Sjaap /*	edges->next->next->next = linegen (llx, lly, lrx, lry);
266*18196Sjaap /*	edges->next->next->next->next = edges;
267*18196Sjaap /*	opqpoly (
268*18196Sjaap /*		edges,
269*18196Sjaap /*		linelist,
270*18196Sjaap /*		inlines,
271*18196Sjaap /*		outlines,
272*18196Sjaap /*		both
273*18196Sjaap /*	);
274*18196Sjaap /*	edges->next->next->next->next = NULL;
275*18196Sjaap /*	linefree (edges);
276*18196Sjaap /*}
277*18196Sjaap */
278*18196Sjaap 
279*18196Sjaap /*
280*18196Sjaap /*void triangle (x1,y1, x2,y2, x3,y3, linelist, inlines, outlines, both)
281*18196Sjaap /*float x1, y1, x2, y2, x3, y3;
282*18196Sjaap /*LINEPTR linelist;
283*18196Sjaap /*LINEPTR *inlines, *outlines, *both;
284*18196Sjaap /*{
285*18196Sjaap /*	LINEPTR edges;
286*18196Sjaap /*	edges = linegen (x1, y1, x2, y2);
287*18196Sjaap /*	edges->next = linegen (x2, y2, x3, y3);
288*18196Sjaap /*	edges->next->next = linegen (x3, y3, x1, y1);
289*18196Sjaap /*	edges->next->next->next = edges;
290*18196Sjaap /*	opqpoly (
291*18196Sjaap /*		edges,
292*18196Sjaap /*		linelist,
293*18196Sjaap /*		inlines,
294*18196Sjaap /*		outlines,
295*18196Sjaap /*		both
296*18196Sjaap /*	);
297*18196Sjaap /*	edges->next->next->next = NULL;
298*18196Sjaap /*	linefree (edges);
299*18196Sjaap /*}
300*18196Sjaap */
301