|
|
1.1 ! root 1: #include "ideal.h" ! 2: #include "y.tab.h" ! 3: ! 4: extern float interalpha[INTERSIZE]; ! 5: extern int internum; ! 6: ! 7: void opqpoly (edgelist, linelist, inlines, outlines, both) ! 8: EDGEPTR edgelist; ! 9: LINEPTR linelist; ! 10: LINEPTR *inlines, *outlines, *both; ! 11: { ! 12: LINEPTR linewalk, circlearc; ! 13: LINENODE nuin, nuout, nuboth; ! 14: LINEPTR inwalk, outwalk, bothwalk; ! 15: LINEPTR forfreeing; ! 16: ! 17: inwalk = &nuin; ! 18: inwalk->next = NULL; ! 19: outwalk = &nuout; ! 20: outwalk->next = NULL; ! 21: bothwalk = &nuboth; ! 22: bothwalk->next = NULL; ! 23: linewalk = linelist; ! 24: while (linewalk) { ! 25: while (inwalk->next) ! 26: inwalk = inwalk->next; ! 27: while (outwalk->next) ! 28: outwalk = outwalk->next; ! 29: while (bothwalk->next) ! 30: bothwalk = bothwalk->next; ! 31: switch (linewalk->kind) { ! 32: case LINE: ! 33: polyline ( ! 34: edgelist, ! 35: linewalk->x0, ! 36: linewalk->y0, ! 37: linewalk->x1, ! 38: linewalk->y1, ! 39: &inwalk->next, ! 40: &outwalk->next, ! 41: &bothwalk->next ! 42: ); ! 43: forfreeing = linewalk; ! 44: linewalk = linewalk->next; ! 45: tryfree(forfreeing); ! 46: break; ! 47: case CIRCLE: ! 48: circlearc = angularc ( ! 49: ((CIRCPTR) linewalk)->x0, ! 50: ((CIRCPTR) linewalk)->y0, ! 51: ((CIRCPTR) linewalk)->r, ! 52: 0.0, ! 53: 2.0*PI ! 54: ); ! 55: circlearc->next = linewalk->next; ! 56: tryfree(linewalk); ! 57: linewalk = circlearc; ! 58: /* FALL THROUGH TO case arc */ ! 59: case ARC: ! 60: polyarc ( ! 61: edgelist, ! 62: ((ARCPTR) linewalk)->x0, ! 63: ((ARCPTR) linewalk)->y0, ! 64: ((ARCPTR) linewalk)->radius, ! 65: ((ARCPTR) linewalk)->theta1, ! 66: ((ARCPTR) linewalk)->theta2, ! 67: &inwalk->next, ! 68: &outwalk->next, ! 69: &bothwalk->next ! 70: ); ! 71: forfreeing = linewalk; ! 72: linewalk = linewalk->next; ! 73: tryfree(forfreeing); ! 74: break; ! 75: case STRING: ! 76: /* ! 77: fprintf (stderr, "ideal: can't opaque over strings\n"); ! 78: */ ! 79: bothwalk->next = linewalk; ! 80: linewalk = linewalk->next; ! 81: bothwalk->next->next = NULL; ! 82: break; ! 83: case SPLINE: ! 84: /* ! 85: fprintf (stderr, "ideal: can't opaque over splines\n"); ! 86: */ ! 87: bothwalk->next = linewalk; ! 88: linewalk = linewalk->next; ! 89: bothwalk->next->next = NULL; ! 90: break; ! 91: default: ! 92: impossible ("opqpoly"); ! 93: break; ! 94: } /* switch */ ! 95: } /* while */ ! 96: *inlines = nuin.next; ! 97: *outlines = nuout.next; ! 98: *both = nuboth.next; ! 99: } /* opqpoly */ ! 100: ! 101: boolean oppose (x0, y0, x1, y1, px0, py0, px1, py1) ! 102: float x0, y0, x1, y1, px0, py0, px1, py1; ! 103: { ! 104: /* returns TRUE iff ! 105: /* p0 and p1 lie on opposite sides of the line through points 0,1 */ ! 106: float alpha, beta; ! 107: boolean collinear; ! 108: ! 109: if (llinter ( ! 110: x0, y0, x1, y1, ! 111: px0, py0, px1, py1, ! 112: &alpha, &beta, &collinear ! 113: )) { ! 114: if (beta < EPSILON) ! 115: return FALSE; ! 116: if (beta > 1.0-EPSILON) ! 117: return FALSE; ! 118: return TRUE; ! 119: } else ! 120: return FALSE; ! 121: } ! 122: ! 123: boolean lcross (cx0, cy0, cx1, cy1, ! 124: px0, py0, qx0, qy0, tx0, ty0, ! 125: px1, py1, qx1, qy1, tx1, ty1) ! 126: float cx0, cy0, cx1, cy1, ! 127: px0, py0, qx0, qy0, tx0, ty0, ! 128: px1, py1, qx1, qy1, tx1, ty1; ! 129: { ! 130: /* line goes through c0 and c1 ! 131: /* p0 and p1 lie on line ! 132: /* q0 and q1 are other ends of edges ! 133: /* t0 and t1 are tangents to edges at p0 and p1 ! 134: /* returns TRUE iff line crosses edges at p0--p1 */ ! 135: float x0, y0, x1, y1; ! 136: if (arecollinear(cx0, cy0, cx1, cy1, tx0, ty0)) { ! 137: x0 = qx0; ! 138: y0 = qy0; ! 139: } else { ! 140: x0 = tx0; ! 141: y0 = ty0; ! 142: } ! 143: if (arecollinear(cx0, cy0, cx1, cy1, tx1, ty1)) { ! 144: x1 = qx1; ! 145: y1 = qy1; ! 146: } else { ! 147: x1 = tx1; ! 148: y1 = ty1; ! 149: } ! 150: return oppose (cx0, cy0, cx1, cy1, x0, y0, x1, y1); ! 151: } ! 152: ! 153: void polyline (edgelist, candx0,candy0, candx1,candy1, inlines, outlines, both) ! 154: EDGEPTR edgelist; ! 155: float candx0,candy0, candx1,candy1; ! 156: LINEPTR *inlines, *outlines, *both; ! 157: { ! 158: OPQPTR interwalk; ! 159: boolean inside, onedge; ! 160: LINENODE nuin, nuout; ! 161: LINEPTR inwalk, outwalk; ! 162: LINEPTR linewalk; ! 163: EDGEPTR prevedge, curedge; ! 164: OPQPTR alphalist; ! 165: float alpha, beta; ! 166: float gamma[2], theta[2]; ! 167: boolean collinear; ! 168: boolean X, Y, Z, W; ! 169: int i; ! 170: double dummy, rem; ! 171: ! 172: alphalist = (OPQPTR) NULL; ! 173: inwalk = &nuin; ! 174: inwalk->next = NULL; ! 175: outwalk = &nuout; ! 176: outwalk->next = NULL; ! 177: curedge = edgelist; ! 178: do { ! 179: if (curedge->fax == NULL) { ! 180: if ( ! 181: llinter ( ! 182: candx0, candy0, ! 183: candx1, candy1, ! 184: curedge->sx, curedge->sy, ! 185: curedge->ex, curedge->ey, ! 186: &alpha, ! 187: &beta, ! 188: &collinear ! 189: ) ! 190: ) { ! 191: if (EPSILON < beta && beta < 1.0 - EPSILON) ! 192: curedge->code[0] = SIMPLE; ! 193: else if (fabs(beta) < EPSILON) ! 194: curedge->code[0] = AT0; ! 195: else if (fabs(1.0-beta) < EPSILON) ! 196: curedge->code[0] = AT1; ! 197: else ! 198: curedge->code[0] = UNUSED; ! 199: curedge->alpha[0] = alpha; ! 200: curedge->code[1] = UNUSED; ! 201: } else ! 202: if (collinear) { ! 203: if (fabs(candx1 - candx0) < EPSILON) { ! 204: curedge->alpha[0] = (curedge->sy - candy0)/(candy1 - candy0); ! 205: curedge->alpha[1] = (curedge->ey - candy0)/(candy1 - candy0); ! 206: } else { ! 207: curedge->alpha[0] = (curedge->sx - candx0)/(candx1 - candx0); ! 208: curedge->alpha[1] = (curedge->ex - candx0)/(candx1 - candx0); ! 209: } ! 210: if (curedge->alpha[0] < curedge->alpha[1]) { ! 211: curedge->code[0] = ON0; ! 212: curedge->code[1] = ON1; ! 213: } else { ! 214: curedge->code[0] = ON1; ! 215: curedge->code[1] = ON0; ! 216: } ! 217: } else ! 218: curedge->code[0] = curedge->code[1] = UNUSED; ! 219: } else if (curedge->fax->kind == ARC) { ! 220: if ( ! 221: !lcinter ( ! 222: candx0, candy0, ! 223: candx1, candy1, ! 224: curedge->fax->x0, curedge->fax->y0, ! 225: fabs(curedge->fax->radius), ! 226: &gamma[0], &theta[0], ! 227: &gamma[1], &theta[1] ! 228: ) ! 229: ) { ! 230: curedge->code[0] = curedge->code[1] = UNUSED; ! 231: dprintf "line outside circle\n"); ! 232: } else if (fabs(theta[0] - theta[1]) < EPSILON) { ! 233: if (fabs(theta[0] - curedge->fax->theta1) < EPSILON) { ! 234: curedge->alpha[0] = gamma[0]; ! 235: curedge->code[0] = curedge->flipped?AT1:AT0; ! 236: dprintf "%d\n", curedge->code[0]); ! 237: } else if (fabs(theta[0] - curedge->fax->theta2) < EPSILON) { ! 238: curedge->alpha[0] = gamma[0]; ! 239: curedge->code[0] = curedge->flipped?AT0:AT1; ! 240: dprintf "%d\n", curedge->code[0]); ! 241: } else { ! 242: curedge->code[0] = UNUSED; ! 243: dprintf "line tangent\n"); ! 244: } ! 245: curedge->code[1] = UNUSED; ! 246: } else { ! 247: for (i = 0; i < 2; i ++) { ! 248: dprintf "disposition of %f\n", theta[i]); ! 249: if (curedge->fax->theta2 < 2.0*PI) { ! 250: if (theta[i] - curedge->fax->theta1 < -EPSILON ! 251: || curedge->fax->theta2 - theta[i] < -EPSILON) { ! 252: curedge->code[i] = UNUSED; ! 253: dprintf "intersection off arc\n"); ! 254: continue; ! 255: } ! 256: } ! 257: if (curedge->fax->theta2 >= 2.0*PI) { ! 258: if (theta[i] - curedge->fax->theta1 < -EPSILON ! 259: && curedge->fax->theta2 - theta[i] < 2.0*PI - EPSILON) { ! 260: curedge->code[i] = UNUSED; ! 261: dprintf "intersection off arc\n"); ! 262: continue; ! 263: } ! 264: } ! 265: rem = modf(fabs(theta[i] - curedge->fax->theta1)/(2*PI), &dummy); ! 266: dprintf "rem1 = %f\n", rem); ! 267: if (rem < EPSILON || fabs(1.0-rem) < EPSILON) { ! 268: curedge->alpha[i] = gamma[i]; ! 269: curedge->code[i] = curedge->flipped?AT1:AT0; ! 270: dprintf "%d\n", curedge->code[i]); ! 271: continue; ! 272: } ! 273: rem = modf(fabs(theta[i] - curedge->fax->theta2)/(2*PI), &dummy); ! 274: dprintf "rem2 = %f\n", rem); ! 275: if (rem < EPSILON || fabs(1.0-rem) < EPSILON) { ! 276: curedge->alpha[i] = gamma[i]; ! 277: curedge->code[i] = curedge->flipped?AT0:AT1; ! 278: dprintf "%d\n", curedge->code[i]); ! 279: continue; ! 280: } ! 281: dprintf "simple\n"); ! 282: curedge->code[i] = SIMPLE; ! 283: curedge->alpha[i] = gamma[i]; ! 284: } ! 285: } ! 286: } else ! 287: impossible ("polyline(A)"); ! 288: curedge = curedge->next; ! 289: } while (curedge != edgelist); ! 290: if (dbg) { ! 291: curedge = edgelist; ! 292: do { ! 293: fprintf (stderr, "s (%f,%f); e (%f,%f)\n", ! 294: curedge->sx, curedge->sy, ! 295: curedge->ex, curedge->ey ! 296: ); ! 297: fprintf (stderr, "st (%f,%f); et (%f,%f)\n", ! 298: curedge->stx, curedge->sty, ! 299: curedge->etx, curedge->ety ! 300: ); ! 301: for (i = 0; i < POSSINTER; i ++) ! 302: fprintf (stderr, "%d %f\n", ! 303: curedge->code[i], ! 304: curedge->alpha[i] ! 305: ); ! 306: curedge = curedge->next; ! 307: } while (curedge != edgelist); ! 308: } ! 309: prevedge = edgelist; ! 310: curedge = edgelist->next; ! 311: do { ! 312: for (i = 0; i < POSSINTER; i ++) ! 313: switch (curedge->code[i]) { ! 314: case UNUSED: ! 315: break; ! 316: case SIMPLE: ! 317: opqinsert(SIMPLE, curedge->alpha[i], &alphalist); ! 318: break; ! 319: case AT0: ! 320: if (lcross ( ! 321: candx0, candy0, candx1, candy1, ! 322: curedge->sx, curedge->sy, ! 323: curedge->ex, curedge->ey, ! 324: curedge->stx, curedge->sty, ! 325: prevedge->ex, prevedge->ey, ! 326: prevedge->sx, prevedge->sy, ! 327: prevedge->etx, prevedge->ety ! 328: )) ! 329: opqinsert(SIMPLE, curedge->alpha[i], &alphalist); ! 330: break; ! 331: case AT1: ! 332: /* should be taken care of by next AT0 */ ! 333: break; ! 334: case ON0: ! 335: case ON1: ! 336: if (lcross ( ! 337: candx0, candy0, candx1, candy1, ! 338: prevedge->ex, prevedge->ey, ! 339: prevedge->sx, prevedge->sy, ! 340: prevedge->etx, prevedge->ety, ! 341: curedge->next->sx, curedge->next->sy, ! 342: curedge->next->ex, curedge->next->ey, ! 343: curedge->next->stx, curedge->next->sty ! 344: )) ! 345: opqinsert(INFL0, curedge->alpha[i], &alphalist); ! 346: else ! 347: opqinsert(EXT0, curedge->alpha[i], &alphalist); ! 348: break; ! 349: case TANGENT: ! 350: default: ! 351: impossible ("polyline(B)"); ! 352: break; ! 353: } ! 354: prevedge = curedge; ! 355: curedge = curedge->next; ! 356: } while (prevedge != edgelist); ! 357: opqinsert(INHERIT, 0.0, &alphalist); ! 358: opqinsert(INHERIT, 1.0, &alphalist); ! 359: if (dbg) { ! 360: fprintf (stderr, "interalpha:\n"); ! 361: for (interwalk = alphalist; ! 362: interwalk; ! 363: interwalk = interwalk->next) ! 364: fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha); ! 365: fprintf (stderr, "\n"); ! 366: } ! 367: inside = onedge = FALSE; ! 368: for (interwalk = alphalist; interwalk; interwalk = interwalk->next) ! 369: switch (interwalk->code) { ! 370: case SIMPLE: ! 371: inside = !inside; ! 372: interwalk->code = inside?INBEGIN:OUTBEGIN; ! 373: break; ! 374: case EXT1: ! 375: case EXT0: ! 376: onedge = !onedge; ! 377: interwalk->code = onedge?ONBEGIN:inside?INBEGIN:OUTBEGIN; ! 378: break; ! 379: case INFL1: ! 380: case INFL0: ! 381: onedge = !onedge; ! 382: if (onedge) ! 383: interwalk->code = ONBEGIN; ! 384: else { ! 385: inside = !inside; ! 386: interwalk->code = inside?INBEGIN:OUTBEGIN; ! 387: } ! 388: break; ! 389: case INHERIT: ! 390: case IGNORE: ! 391: interwalk->code = onedge?ONBEGIN:inside?INBEGIN:OUTBEGIN; ! 392: break; ! 393: break; ! 394: default: ! 395: impossible("polyline(C)"); ! 396: break; ! 397: } ! 398: if (dbg) { ! 399: fprintf (stderr, "interalpha:\n"); ! 400: for (interwalk = alphalist; ! 401: interwalk; ! 402: interwalk = interwalk->next) ! 403: fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha); ! 404: fprintf (stderr, "\n"); ! 405: } ! 406: for (interwalk = alphalist; interwalk; interwalk = interwalk->next) { ! 407: linewalk = linegen ( ! 408: candx0 + interwalk->alpha*(candx1 - candx0), ! 409: candy0 + interwalk->alpha*(candy1 - candy0), ! 410: candx0 + interwalk->next->alpha*(candx1 - candx0), ! 411: candy0 + interwalk->next->alpha*(candy1 - candy0) ! 412: ); ! 413: if ( ! 414: interwalk->alpha > -EPSILON ! 415: && interwalk->next ! 416: && interwalk->next->alpha < 1.0 + EPSILON ! 417: ) ! 418: switch (interwalk->code) { ! 419: case INBEGIN: ! 420: inwalk->next = linewalk; ! 421: inwalk = inwalk->next; ! 422: break; ! 423: case OUTBEGIN: ! 424: outwalk->next = linewalk; ! 425: outwalk = outwalk->next; ! 426: break; ! 427: case ONBEGIN: ! 428: tryfree(linewalk); ! 429: break; ! 430: default: ! 431: impossible("polyline(D)"); ! 432: break; ! 433: } ! 434: } ! 435: *inlines = nuin.next; ! 436: *outlines = nuout.next; ! 437: *both = NULL; ! 438: } ! 439: ! 440: #define xtanp(x,y,r,t) x+fabs(r)*cos(t)+sin(t) ! 441: #define ytanp(x,y,r,t) y+fabs(r)*sin(t)-cos(t) ! 442: #define xtane(x,y,r,t) x+fabs(r)*cos(t)-sin(t) ! 443: #define ytane(x,y,r,t) y+fabs(r)*sin(t)+cos(t) ! 444: ! 445: boolean ptinpoly (edgelist, x, y) ! 446: EDGEPTR edgelist; ! 447: float x, y; ! 448: { ! 449: LINEPTR inlines, outlines, both; ! 450: polyline ( ! 451: edgelist, ! 452: x - 100*EPSILON, y - 100*EPSILON, ! 453: x + 100*EPSILON, y + 100*EPSILON, ! 454: &inlines, &outlines, &both ! 455: ); ! 456: if (inlines) { ! 457: if (outlines || both) ! 458: impossible ("ptinpoly(A)"); ! 459: else { ! 460: linefree(inlines); ! 461: dprintf "ptinpoly: TRUE\n"); ! 462: return TRUE; ! 463: } ! 464: } else if (outlines) { ! 465: if (inlines || both) ! 466: impossible ("ptinpoly(B)"); ! 467: else { ! 468: linefree(outlines); ! 469: dprintf "ptinpoly: FALSE\n"); ! 470: return FALSE; ! 471: } ! 472: } else ! 473: impossible ("ptinpoly(C)"); ! 474: } ! 475: ! 476: boolean locin (x0, y0, r, ! 477: qx, qy, tx, ty, ! 478: t1x, t1y, t2x, t2y) ! 479: float x0, y0, r, qx, qy, tx, ty, t1x, t1y, t2x, t2y; ! 480: { ! 481: dprintf "locin\n"); ! 482: if (arecollinear(tx,ty,t1x,t1y,t2x,t2y)) { ! 483: dprintf "arecollinear TRUE\n"); ! 484: return (hypot(x0-qx,y0-qy) < fabs(r)); ! 485: } else ! 486: return !oppose(x0,y0,tx,ty,t1x,t1y,t2x,t2y); ! 487: } ! 488: ! 489: boolean ccross (x0, y0, r, ! 490: p1x, p1y, q1x, q1y, t1x, t1y, ! 491: p2x, p2y, q2x, q2y, t2x, t2y) ! 492: float x0, y0, r, p1x, p1y, q1x, q1y, t1x, t1y, p2x, p2y, q2x, q2y, t2x, t2y; ! 493: { ! 494: float theta1, theta2; ! 495: boolean in1, in2; ! 496: float xt1, yt1, xt2, yt2; ! 497: dprintf "ccross: %f %f %f\n", x0, y0, r); ! 498: dprintf "ccross: %f %f %f %f\n", p1x, p1y, p2x, p2y); ! 499: theta1 = atan2(p1y-y0,p1x-x0); ! 500: theta2 = atan2(p2y-y0,p2x-x0); ! 501: dprintf "ccross: theta1 = %f; theta2 = %f\n", theta1, theta2); ! 502: xt1 = xtanp(x0,y0,r,theta1); ! 503: yt1 = ytanp(x0,y0,r,theta1); ! 504: xt2 = xtane(x0,y0,r,theta1); ! 505: yt2 = ytane(x0,y0,r,theta1); ! 506: dprintf "1:xt1 = %f; yt1 = %f; xt2 = %f; yt2 = %f\n", xt1, yt1, xt2, yt2); ! 507: in1 = locin(x0,y0,r, ! 508: q1x,q1y,t1x,t1y, ! 509: xt1, yt1, xt2, yt2 ! 510: ); ! 511: xt1 = xtanp(x0,y0,r,theta2); ! 512: yt1 = ytanp(x0,y0,r,theta2); ! 513: xt2 = xtane(x0,y0,r,theta2); ! 514: yt2 = ytane(x0,y0,r,theta2); ! 515: dprintf "2:xt1 = %f; yt1 = %f; xt2 = %f; yt2 = %f\n", xt1, yt1, xt2, yt2); ! 516: in2 = locin(x0,y0,r, ! 517: q2x,q2y,t2x,t2y, ! 518: xt1, yt1, xt2, yt2 ! 519: ); ! 520: dprintf "ccross: in1 = %d; in2 = %d\n", in1, in2); ! 521: return in1 ^ in2; ! 522: } ! 523: ! 524: void polyarc (edgelist, x0,y0, radius, startang, endang, inlines, outlines, both) ! 525: EDGEPTR edgelist; ! 526: float x0, y0, radius, startang, endang; ! 527: LINEPTR *inlines, *outlines, *both; ! 528: { ! 529: OPQPTR interwalk; ! 530: boolean inside, onedge; ! 531: LINENODE nuin, nuout; ! 532: LINEPTR inwalk, outwalk; ! 533: LINEPTR linewalk; ! 534: EDGEPTR prevedge, curedge; ! 535: OPQPTR alphalist; ! 536: float alpha[2], beta[2], gamma[2], theta[2]; ! 537: boolean collinear; ! 538: boolean X, Y, Z, W; ! 539: float stx, sty, etx, ety; ! 540: int i; ! 541: double dummy, rem; ! 542: ! 543: alphalist = (OPQPTR) NULL; ! 544: inwalk = &nuin; ! 545: inwalk->next = NULL; ! 546: outwalk = &nuout; ! 547: outwalk->next = NULL; ! 548: curedge = edgelist; ! 549: do { ! 550: if (curedge->fax == NULL) { ! 551: if ( ! 552: lcinter ( ! 553: curedge->sx, curedge->sy, ! 554: curedge->ex, curedge->ey, ! 555: x0, y0, ! 556: radius, ! 557: &alpha[0], &theta[0], ! 558: &alpha[1], &theta[1] ! 559: ) ! 560: ) { ! 561: if (fabs(theta[0] - theta[1]) < EPSILON) { ! 562: if (fabs(alpha[0]) < EPSILON) ! 563: curedge->code[0] = AT0; ! 564: else if (fabs(1.0-alpha[0]) < EPSILON) ! 565: curedge->code[0] = AT1; ! 566: else ! 567: curedge->code[0] = TANGENT; ! 568: curedge->alpha[0] = rprin(theta[0]); ! 569: curedge->code[1] = UNUSED; ! 570: } else { ! 571: for (i = 0; i < 2; i ++) { ! 572: if (EPSILON < alpha[i] && alpha[i] < 1.0 - EPSILON) ! 573: curedge->code[i] = SIMPLE; ! 574: else if (fabs(alpha[i]) < EPSILON) ! 575: curedge->code[i] = AT0; ! 576: else if (fabs(alpha[i] - 1.0) < EPSILON) ! 577: curedge->code[i] = AT1; ! 578: else ! 579: curedge->code[i] = UNUSED; ! 580: curedge->alpha[i] = rprin(theta[i]); ! 581: } ! 582: } ! 583: } else { ! 584: curedge->code[0] = curedge->code[1] = UNUSED; ! 585: } ! 586: } else if (curedge->fax->kind == ARC) { ! 587: if (!ccinter ( ! 588: x0, y0, ! 589: radius, ! 590: curedge->fax->x0, curedge->fax->y0, ! 591: curedge->fax->radius, ! 592: &gamma[0], &theta[0], ! 593: &gamma[1], &theta[1] ! 594: ) ! 595: ) { ! 596: if (fabs(x0 - curedge->fax->x0) < EPSILON ! 597: && fabs(y0 - curedge->fax->y0) < EPSILON ! 598: && fabs(fabs(radius) - fabs(curedge->fax->radius)) < EPSILON ! 599: ) { ! 600: curedge->alpha[0] = rprin(curedge->fax->theta1); ! 601: curedge->alpha[1] = rprin(curedge->fax->theta2); ! 602: curedge->code[0] = ON0; ! 603: curedge->code[1] = ON1; ! 604: } else { ! 605: curedge->code[0] = curedge->code[1] = UNUSED; ! 606: } ! 607: } else if (fabs(theta[0] - theta[1]) < EPSILON) { ! 608: if (fabs(theta[0] - curedge->fax->theta1) < EPSILON) ! 609: curedge->code[0] = curedge->flipped?AT1:AT0; ! 610: else if (fabs(theta[0] - curedge->fax->theta2) < EPSILON) ! 611: curedge->code[0] = curedge->flipped?AT0:AT1; ! 612: else ! 613: curedge->code[0] = TANGENT; ! 614: curedge->alpha[0] = rprin(gamma[0]); ! 615: curedge->code[1] = UNUSED; ! 616: } else { ! 617: for (i = 0; i < 2; i ++) { ! 618: dprintf "disposition of %f\n", theta[i]); ! 619: if (curedge->fax->theta2 < 2.0*PI) { ! 620: if (theta[i] - curedge->fax->theta1 < -EPSILON ! 621: || curedge->fax->theta2 - theta[i] < -EPSILON) { ! 622: curedge->code[i] = UNUSED; ! 623: dprintf "intersection off arc\n"); ! 624: continue; ! 625: } ! 626: } ! 627: if (curedge->fax->theta2 > 2.0*PI) { ! 628: if (theta[i] - curedge->fax->theta1 < -EPSILON ! 629: && curedge->fax->theta2 - theta[i] < 2.0*PI - EPSILON) { ! 630: curedge->code[i] = UNUSED; ! 631: dprintf "intersection off arc\n"); ! 632: continue; ! 633: } ! 634: } ! 635: rem = modf(fabs(theta[i] - curedge->fax->theta1)/(2.0*PI), &dummy); ! 636: dprintf "rem1 = %f\n", rem); ! 637: if (rem < EPSILON || fabs(1.0 - rem) < EPSILON) { ! 638: curedge->alpha[i] = rprin(gamma[i]); ! 639: curedge->code[i] = curedge->flipped?AT1:AT0; ! 640: continue; ! 641: } ! 642: rem = modf(fabs(theta[i] - curedge->fax->theta2)/(2.0*PI), &dummy); ! 643: dprintf "rem2 = %f\n", rem); ! 644: if (rem < EPSILON || fabs(1.0 - rem) < EPSILON) { ! 645: curedge->alpha[i] = rprin(gamma[i]); ! 646: curedge->code[i] = curedge->flipped?AT0:AT1; ! 647: continue; ! 648: } ! 649: dprintf "simple\n"); ! 650: curedge->code[i] = SIMPLE; ! 651: curedge->alpha[i] = rprin(gamma[i]); ! 652: } ! 653: } ! 654: } else { ! 655: impossible ("polyarc(D)"); ! 656: } ! 657: curedge = curedge->next; ! 658: } while (curedge != edgelist); ! 659: if (dbg) { ! 660: curedge = edgelist; ! 661: do { ! 662: fprintf (stderr, "s (%f,%f); e (%f,%f)\n", ! 663: curedge->sx, curedge->sy, ! 664: curedge->ex, curedge->ey ! 665: ); ! 666: fprintf (stderr, "st (%f,%f); et (%f,%f)\n", ! 667: curedge->stx, curedge->sty, ! 668: curedge->etx, curedge->ety ! 669: ); ! 670: for (i = 0; i < POSSINTER; i ++) ! 671: fprintf (stderr, "%d %f\n", ! 672: curedge->code[i], ! 673: curedge->alpha[i] ! 674: ); ! 675: curedge = curedge->next; ! 676: } while (curedge != edgelist); ! 677: } ! 678: prevedge = edgelist; ! 679: curedge = edgelist->next; ! 680: do { ! 681: for (i = 0; i < POSSINTER; i ++) { ! 682: stx = xtanp(x0,y0,radius,curedge->alpha[i]); ! 683: sty = ytanp(x0,y0,radius,curedge->alpha[i]); ! 684: etx = xtane(x0,y0,radius,curedge->alpha[i]); ! 685: ety = ytane(x0,y0,radius,curedge->alpha[i]); ! 686: switch (curedge->code[i]) { ! 687: case UNUSED: ! 688: break; ! 689: case SIMPLE: ! 690: opqinsert(SIMPLE, curedge->alpha[i], &alphalist); ! 691: break; ! 692: case AT0: ! 693: dprintf "AT0\n"); ! 694: if (ccross(x0,y0,radius, ! 695: curedge->sx, curedge->sy, ! 696: curedge->ex, curedge->ey, ! 697: curedge->stx, curedge->sty, ! 698: prevedge->ex, prevedge->ey, ! 699: prevedge->sx, prevedge->sy, ! 700: prevedge->etx, prevedge->ety ! 701: )) ! 702: opqinsert(SIMPLE, curedge->alpha[i], &alphalist); ! 703: else ! 704: opqinsert(IGNORE, curedge->alpha[i], &alphalist); ! 705: break; ! 706: case AT1: ! 707: /* should be taken care of by next AT0 */ ! 708: break; ! 709: case ON0: ! 710: case ON1: ! 711: dprintf "ON\n"); ! 712: if (ccross(x0,y0,radius, ! 713: prevedge->ex, prevedge->ey, ! 714: prevedge->sx, prevedge->sy, ! 715: prevedge->etx, prevedge->ety, ! 716: curedge->next->sx, curedge->next->sy, ! 717: curedge->next->ex, curedge->next->ey, ! 718: curedge->next->stx, curedge->next->sty ! 719: )) ! 720: opqinsert((curedge->code[i] == ON0)?INFL0:INFL1, curedge->alpha[i], &alphalist); ! 721: else ! 722: opqinsert((curedge->code[i] == ON0)?EXT0:EXT1, curedge->alpha[i], &alphalist); ! 723: break; ! 724: case TANGENT: ! 725: opqinsert(IGNORE, curedge->alpha[i], &alphalist); ! 726: break; ! 727: default: ! 728: impossible ("polyline(B)"); ! 729: break; ! 730: } ! 731: } ! 732: prevedge = curedge; ! 733: curedge = curedge->next; ! 734: } while (prevedge != edgelist); ! 735: opqinsert(INHERIT, rprin(startang), &alphalist); ! 736: opqinsert(INHERIT, rprin(endang), &alphalist); ! 737: if (dbg) { ! 738: fprintf (stderr, "interalpha:\n"); ! 739: for (interwalk = alphalist; ! 740: interwalk; ! 741: interwalk = interwalk->next) ! 742: fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha); ! 743: fprintf (stderr, "\n"); ! 744: } ! 745: ((OPQPTR) tail((NAMEPTR) alphalist))->next = alphalist; ! 746: interwalk = alphalist; ! 747: onedge = FALSE; ! 748: do { ! 749: switch (interwalk->code) { ! 750: case EXT0: ! 751: alpha[0] = interwalk->alpha; ! 752: onedge = TRUE; ! 753: break; ! 754: case EXT1: ! 755: alpha[1] = interwalk->alpha; ! 756: onedge = TRUE; ! 757: break; ! 758: case INFL0: ! 759: alpha[0] = interwalk->alpha; ! 760: onedge = TRUE; ! 761: break; ! 762: case INFL1: ! 763: alpha[1] = interwalk->alpha; ! 764: onedge = TRUE; ! 765: break; ! 766: default: ! 767: break; ! 768: } ! 769: interwalk = interwalk->next; ! 770: } while (interwalk != alphalist); ! 771: if (onedge) { ! 772: rem = modf(fabs(alpha[0]-alpha[1])/(2.0*PI), &dummy); ! 773: if (rem < EPSILON || fabs(1.0-rem) < EPSILON) ! 774: return; ! 775: } ! 776: interwalk = alphalist; ! 777: do { ! 778: if (interwalk->code == EXT0 || interwalk->code == INFL0 || interwalk->code == INHERIT) ! 779: interwalk = interwalk->next; ! 780: else ! 781: break; ! 782: } while (interwalk != alphalist); ! 783: rem = modf(fabs(interwalk->alpha - interwalk->next->alpha)/(2.0*PI), &dummy); ! 784: if (rem < EPSILON || fabs(1.0-rem) < EPSILON) ! 785: interwalk = interwalk->next; ! 786: inside = ptinpoly ( ! 787: edgelist, ! 788: x0 + fabs(radius)*cos((interwalk->alpha + interwalk->next->alpha)/2.0), ! 789: y0 + fabs(radius)*sin((interwalk->alpha + interwalk->next->alpha)/2.0) ! 790: ); ! 791: dprintf "inside: %d\n", inside); ! 792: alphalist = interwalk->next; ! 793: interwalk = alphalist; ! 794: onedge = FALSE; ! 795: do { ! 796: switch (interwalk->code) { ! 797: case SIMPLE: ! 798: interwalk->code = (!inside)?INBEGIN:OUTBEGIN; ! 799: inside = !inside; ! 800: break; ! 801: case EXT1: ! 802: interwalk->code = inside?INBEGIN:OUTBEGIN; ! 803: onedge = FALSE; ! 804: break; ! 805: case EXT0: ! 806: interwalk->code = ONBEGIN; ! 807: onedge = TRUE; ! 808: break; ! 809: case INFL1: ! 810: interwalk->code = (!inside)?INBEGIN:OUTBEGIN; ! 811: inside = !inside; ! 812: onedge = FALSE; ! 813: break; ! 814: case INFL0: ! 815: interwalk->code = ONBEGIN; ! 816: onedge = TRUE; ! 817: break; ! 818: case INHERIT: ! 819: case IGNORE: ! 820: interwalk->code = onedge?ONBEGIN:(inside?INBEGIN:OUTBEGIN); ! 821: break; ! 822: default: ! 823: impossible("polyline(C)"); ! 824: break; ! 825: } ! 826: interwalk = interwalk->next; ! 827: } while (interwalk != alphalist); ! 828: while (alphalist->alpha < alphalist->next->alpha) ! 829: alphalist = alphalist->next; ! 830: alphalist = alphalist->next; ! 831: if (dbg) { ! 832: fprintf (stderr, "interalpha:\n"); ! 833: interwalk = alphalist; ! 834: do { ! 835: fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha); ! 836: interwalk = interwalk->next; ! 837: } while (interwalk != alphalist); ! 838: fprintf (stderr, "\n"); ! 839: } ! 840: interwalk = alphalist; ! 841: do { ! 842: if (interwalk->alpha > interwalk->next->alpha) ! 843: break; ! 844: if (endang < 2.0*PI + EPSILON) { ! 845: if (interwalk->alpha < startang - EPSILON || interwalk->alpha > endang + EPSILON) { ! 846: dprintf "arc rejected (A)\n"); ! 847: interwalk = interwalk->next; ! 848: continue; ! 849: } ! 850: if (interwalk->next->alpha < startang - EPSILON || interwalk->next->alpha > endang + EPSILON) { ! 851: dprintf "arc rejected (B)\n"); ! 852: interwalk = interwalk->next; ! 853: continue; ! 854: } ! 855: } else { ! 856: if (interwalk->alpha < startang - EPSILON && interwalk->alpha > endang + EPSILON - 2.0*PI) { ! 857: dprintf "arc rejected (C)\n"); ! 858: interwalk = interwalk->next; ! 859: continue; ! 860: } ! 861: if (interwalk->next->alpha < startang - EPSILON && interwalk->next->alpha > endang + EPSILON - 2.0*PI) { ! 862: dprintf "arc rejected (D)\n"); ! 863: interwalk = interwalk->next; ! 864: continue; ! 865: } ! 866: } ! 867: linewalk = angularc ( ! 868: x0, y0, ! 869: radius, ! 870: interwalk->alpha, ! 871: interwalk->next->alpha ! 872: ); ! 873: switch (interwalk->code) { ! 874: case INBEGIN: ! 875: inwalk->next = linewalk; ! 876: inwalk = inwalk->next; ! 877: break; ! 878: case OUTBEGIN: ! 879: outwalk->next = linewalk; ! 880: outwalk = outwalk->next; ! 881: break; ! 882: case ONBEGIN: ! 883: tryfree(linewalk); ! 884: break; ! 885: default: ! 886: impossible("polyline(D)"); ! 887: break; ! 888: } ! 889: interwalk = interwalk->next; ! 890: } while (interwalk != alphalist); ! 891: *inlines = nuin.next; ! 892: *outlines = nuout.next; ! 893: *both = NULL; ! 894: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.