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