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 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 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 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