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