00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "render.h"
00019 #include "pathplan.h"
00020
00021 #ifdef UNUSED
00022 static box *bs = NULL;
00023 static int bn;
00024 static int maxbn = 0;
00025 #define BINC 300
00026 #endif
00027
00028 #define PINC 300
00029
00030 #ifdef NOTNOW
00031 static edge_t *origedge;
00032 #endif
00033
00034 static int nedges, nboxes;
00035
00036 static int routeinit;
00037
00038 static point *ps;
00039 static int maxpn;
00040 static Ppoint_t *polypoints;
00041 static int polypointn;
00042 static Pedge_t *edges;
00043 static int edgen;
00044
00045 static void checkpath(int, box*, path*);
00046 static void mkspacep(int size);
00047 static void printpath(path * pp);
00048 #ifdef OBSOLETE
00049 static int append(path * path, int bi, point p0, point p1, int);
00050 #endif
00051 #ifdef DEBUG
00052 static void printboxes(int boxn, box* boxes)
00053 {
00054 point ll, ur;
00055 int bi;
00056 char buf[BUFSIZ];
00057 int newcnt = Show_cnt + boxn;
00058
00059 Show_boxes = ALLOC(newcnt+2,Show_boxes,char*);
00060 for (bi = 0; bi < boxn; bi++) {
00061 ll = boxes[bi].LL, ur = boxes[bi].UR;
00062 sprintf(buf, "%d %d %d %d pathbox", ll.x, ll.y, ur.x, ur.y);
00063 Show_boxes[bi+1+Show_cnt] = strdup (buf);
00064 }
00065 Show_cnt = newcnt;
00066 Show_boxes[Show_cnt+1] = NULL;
00067 }
00068
00069 static void psprintpolypts(Ppoint_t * p, int sz)
00070 {
00071 int i;
00072
00073 fprintf(stderr, "%%!\n");
00074 fprintf(stderr, "%% constraint poly\n");
00075 fprintf(stderr, "newpath\n");
00076 for (i = 0; i < sz; i++)
00077 fprintf(stderr, "%f %f %s\n", p[i].x, p[i].y,
00078 (i == 0 ? "moveto" : "lineto"));
00079 fprintf(stderr, "closepath stroke\n");
00080 }
00081 static void psprintpoint(point p)
00082 {
00083 fprintf(stderr, "gsave\n");
00084 fprintf(stderr,
00085 "newpath %d %d moveto %d %d 2 0 360 arc closepath fill stroke\n",
00086 p.x, p.y, p.x, p.y);
00087 fprintf(stderr, "/Times-Roman findfont 4 scalefont setfont\n");
00088 fprintf(stderr, "%d %d moveto (\\(%d,%d\\)) show\n", p.x + 5, p.y + 5,
00089 p.x, p.y);
00090 fprintf(stderr, "grestore\n");
00091 }
00092
00093 static void psprintspline(Ppolyline_t spl)
00094 {
00095 char buf[BUFSIZ];
00096 int newcnt = Show_cnt + spl.pn + 4;
00097 int li, i;
00098
00099 Show_boxes = ALLOC(newcnt+2,Show_boxes,char*);
00100 li = Show_cnt+1;
00101 Show_boxes[li++] = strdup ("%%!");
00102 Show_boxes[li++] = strdup ("%% spline");
00103 Show_boxes[li++] = strdup ("gsave 1 0 0 setrgbcolor newpath");
00104 for (i = 0; i < spl.pn; i++) {
00105 sprintf(buf, "%f %f %s", spl.ps[i].x, spl.ps[i].y,
00106 (i == 0) ? "moveto" : ((i % 3 == 0) ? "curveto" : ""));
00107 Show_boxes[li++] = strdup (buf);
00108 }
00109 Show_boxes[li++] = strdup ("stroke grestore");
00110 Show_cnt = newcnt;
00111 Show_boxes[Show_cnt+1] = NULL;
00112 }
00113
00114 static void psprintline(Ppolyline_t pl)
00115 {
00116 char buf[BUFSIZ];
00117 int newcnt = Show_cnt + pl.pn + 4;
00118 int i, li;
00119
00120 Show_boxes = ALLOC(newcnt+2,Show_boxes,char*);
00121 li = Show_cnt+1;
00122 Show_boxes[li++] = strdup ("%%!");
00123 Show_boxes[li++] = strdup ("%% line");
00124 Show_boxes[li++] = strdup ("gsave 0 0 1 setrgbcolor newpath");
00125 for (i = 0; i < pl.pn; i++) {
00126 sprintf(buf, "%f %f %s", pl.ps[i].x, pl.ps[i].y,
00127 (i == 0 ? "moveto" : "lineto"));
00128 Show_boxes[li++] = strdup (buf);
00129 }
00130 Show_boxes[li++] = strdup ("stroke grestore");
00131 Show_cnt = newcnt;
00132 Show_boxes[Show_cnt+1] = NULL;
00133 }
00134
00135 static void psprintpoly(Ppoly_t p)
00136 {
00137 char buf[BUFSIZ];
00138 int newcnt = Show_cnt + p.pn + 3;
00139 point tl, hd;
00140 int bi, li;
00141 char* pfx;
00142
00143 Show_boxes = ALLOC(newcnt+2,Show_boxes,char*);
00144 li = Show_cnt+1;
00145 Show_boxes[li++] = strdup ("%% poly list");
00146 Show_boxes[li++] = strdup ("gsave 0 1 0 setrgbcolor");
00147 for (bi = 0; bi < p.pn; bi++) {
00148 tl.x = (int)p.ps[bi].x;
00149 tl.y = (int)p.ps[bi].y;
00150 hd.x = (int)p.ps[(bi+1) % p.pn].x;
00151 hd.y = (int)p.ps[(bi+1) % p.pn].y;
00152 if ((tl.x == hd.x) && (tl.y == hd.y)) pfx = "%%";
00153 else pfx ="";
00154 sprintf(buf, "%s%d %d %d %d makevec", pfx, tl.x, tl.y, hd.x, hd.y);
00155 Show_boxes[li++] = strdup (buf);
00156 }
00157 Show_boxes[li++] = strdup ("grestore");
00158
00159 Show_cnt = newcnt;
00160 Show_boxes[Show_cnt+1] = NULL;
00161 }
00162
00163 static void psprintboxes(int boxn, box* boxes)
00164 {
00165 char buf[BUFSIZ];
00166 int newcnt = Show_cnt + 5*boxn + 3;
00167 point ll, ur;
00168 int bi, li;
00169
00170 Show_boxes = ALLOC(newcnt+2,Show_boxes,char*);
00171 li = Show_cnt+1;
00172 Show_boxes[li++] = strdup ("%% box list");
00173 Show_boxes[li++] = strdup ("gsave 0 1 0 setrgbcolor");
00174 for (bi = 0; bi < boxn; bi++) {
00175 ll = boxes[bi].LL, ur = boxes[bi].UR;
00176 sprintf(buf, "newpath\n%d %d moveto", ll.x, ll.y);
00177 Show_boxes[li++] = strdup (buf);
00178 sprintf(buf, "%d %d lineto", ll.x, ur.y);
00179 Show_boxes[li++] = strdup (buf);
00180 sprintf(buf, "%d %d lineto", ur.x, ur.y);
00181 Show_boxes[li++] = strdup (buf);
00182 sprintf(buf, "%d %d lineto", ur.x, ll.y);
00183 Show_boxes[li++] = strdup (buf);
00184 Show_boxes[li++] = strdup ("closepath stroke");
00185 }
00186 Show_boxes[li++] = strdup ("grestore");
00187
00188 Show_cnt = newcnt;
00189 Show_boxes[Show_cnt+1] = NULL;
00190 }
00191
00192 static void psprintinit (int begin)
00193 {
00194 int newcnt = Show_cnt + 1;
00195
00196 Show_boxes = ALLOC(newcnt+2,Show_boxes,char*);
00197 if (begin)
00198 Show_boxes[1+Show_cnt] = strdup ("dbgstart");
00199 else
00200 Show_boxes[1+Show_cnt] = strdup ("grestore");
00201 Show_cnt = newcnt;
00202 Show_boxes[Show_cnt+1] = NULL;
00203 }
00204
00205 static int debugleveln(edge_t* realedge, int i)
00206 {
00207 return (GD_showboxes(realedge->head->graph) == i ||
00208 GD_showboxes(realedge->tail->graph) == i ||
00209 ED_showboxes(realedge) == i ||
00210 ND_showboxes(realedge->head) == i ||
00211 ND_showboxes(realedge->tail) == i);
00212 }
00213 #endif
00214
00215 #ifdef OBSOLETE
00216 static point mkpt(int x, int y)
00217 {
00218 point rv;
00219 rv.x = x;
00220 rv.y = y;
00221 return rv;
00222 }
00223
00224 static int pteq(point p, point q)
00225 {
00226 return ((p.x == q.x) && (p.y == q.y));
00227 }
00228 #endif
00229
00230
00231
00232
00233
00234 void
00235 routesplinesinit()
00236 {
00237 if (++routeinit > 1) return;
00238 #ifdef UNUSED
00239 if (!(bs = N_GNEW(BINC, box))) {
00240 agerr(AGERR, "cannot allocate bs\n");
00241 abort();
00242 }
00243 maxbn = BINC;
00244 #endif
00245 if (!(ps = N_GNEW(PINC, point))) {
00246 agerr(AGERR, "cannot allocate ps\n");
00247 abort();
00248 }
00249 maxpn = PINC;
00250 #ifdef DEBUG
00251 if (Show_boxes) {
00252 int i;
00253 for (i = 0; Show_boxes[i]; i++)
00254 free (Show_boxes[i]);
00255 free (Show_boxes);
00256 Show_boxes = NULL;
00257 Show_cnt = 0;
00258 }
00259 #endif
00260 nedges = 0;
00261 nboxes = 0;
00262 if (Verbose)
00263 start_timer();
00264 }
00265
00266 void routesplinesterm()
00267 {
00268 if (--routeinit > 0) return;
00269 free(ps);
00270 #ifdef UNUSED
00271 free(bs), bs = NULL ;
00272 #endif
00273 if (Verbose)
00274 fprintf(stderr,
00275 "routesplines: %d edges, %d boxes %.2f sec\n",
00276 nedges, nboxes, elapsed_sec());
00277 }
00278
00279 static point *_routesplines(path * pp, int *npoints, int polyline)
00280 {
00281 Ppoly_t poly;
00282 Ppolyline_t pl, spl;
00283 int splinepi;
00284 Ppoint_t eps[2];
00285 Pvector_t evs[2];
00286 int edgei, prev, next;
00287 point sp[4];
00288 int pi, bi, si;
00289 double t;
00290 box *boxes;
00291 int boxn;
00292 edge_t* realedge;
00293 int flip;
00294 int delta = 10;
00295
00296 nedges++;
00297 nboxes += pp->nbox;
00298
00299 for (realedge = (edge_t *) pp->data;
00300 #ifdef NOTNOW
00301 origedge = realedge;
00302 #endif
00303 realedge && ED_edge_type(realedge) != NORMAL;
00304 realedge = ED_to_orig(realedge));
00305 if (!realedge) {
00306 agerr(AGERR, "in routesplines, cannot find NORMAL edge\n");
00307 abort();
00308 }
00309
00310 boxes = pp->boxes;
00311 boxn = pp->nbox;
00312
00313 checkpath(boxn, boxes, pp);
00314
00315 #ifdef DEBUG
00316 if (debugleveln(realedge, 1))
00317 printboxes(boxn, boxes);
00318 if (debugleveln(realedge, 3)) {
00319 psprintinit(1);
00320 psprintboxes(boxn, boxes);
00321 }
00322 #endif
00323
00324 if (boxn * 8 > polypointn) {
00325 polypoints = ALLOC(boxn * 8, polypoints, Ppoint_t);
00326 polypointn = boxn * 8;
00327 }
00328
00329 if ((boxn > 1) && (boxes[0].LL.y > boxes[1].LL.y)) {
00330 flip = 1;
00331 for (bi = 0; bi < boxn; bi++) {
00332 int v = boxes[bi].UR.y;
00333 boxes[bi].UR.y = -1*boxes[bi].LL.y;
00334 boxes[bi].LL.y = -v;
00335 }
00336 }
00337 else flip = 0;
00338
00339 if (realedge->tail != realedge->head) {
00340
00341
00342 for (bi = 0, pi = 0; bi < boxn; bi++) {
00343 next = prev = 0;
00344 if (bi > 0)
00345 prev = (boxes[bi].LL.y > boxes[bi - 1].LL.y) ? -1 : 1;
00346 if (bi < boxn - 1)
00347 next = (boxes[bi + 1].LL.y > boxes[bi].LL.y) ? 1 : -1;
00348 if (prev != next) {
00349 if (next == -1 || prev == 1) {
00350 polypoints[pi].x = boxes[bi].LL.x;
00351 polypoints[pi++].y = boxes[bi].UR.y;
00352 polypoints[pi].x = boxes[bi].LL.x;
00353 polypoints[pi++].y = boxes[bi].LL.y;
00354 } else {
00355 polypoints[pi].x = boxes[bi].UR.x;
00356 polypoints[pi++].y = boxes[bi].LL.y;
00357 polypoints[pi].x = boxes[bi].UR.x;
00358 polypoints[pi++].y = boxes[bi].UR.y;
00359 }
00360 }
00361 else if (prev == 0) {
00362 polypoints[pi].x = boxes[bi].LL.x;
00363 polypoints[pi++].y = boxes[bi].UR.y;
00364 polypoints[pi].x = boxes[bi].LL.x;
00365 polypoints[pi++].y = boxes[bi].LL.y;
00366 }
00367 else {
00368 if (!(prev == -1 && next == -1))
00369 abort();
00370 }
00371 }
00372 for (bi = boxn - 1; bi >= 0; bi--) {
00373 next = prev = 0;
00374 if (bi < boxn - 1)
00375 prev = (boxes[bi].LL.y > boxes[bi + 1].LL.y) ? -1 : 1;
00376 if (bi > 0)
00377 next = (boxes[bi - 1].LL.y > boxes[bi].LL.y) ? 1 : -1;
00378 if (prev != next) {
00379 if (next == -1 || prev == 1 ) {
00380 polypoints[pi].x = boxes[bi].LL.x;
00381 polypoints[pi++].y = boxes[bi].UR.y;
00382 polypoints[pi].x = boxes[bi].LL.x;
00383 polypoints[pi++].y = boxes[bi].LL.y;
00384 } else {
00385 polypoints[pi].x = boxes[bi].UR.x;
00386 polypoints[pi++].y = boxes[bi].LL.y;
00387 polypoints[pi].x = boxes[bi].UR.x;
00388 polypoints[pi++].y = boxes[bi].UR.y;
00389 }
00390 }
00391 else if (prev == 0) {
00392 polypoints[pi].x = boxes[bi].UR.x;
00393 polypoints[pi++].y = boxes[bi].LL.y;
00394 polypoints[pi].x = boxes[bi].UR.x;
00395 polypoints[pi++].y = boxes[bi].UR.y;
00396 }
00397 else {
00398 if (!(prev == -1 && next == -1)) {
00399
00400 *npoints = 0;
00401 abort();
00402 return ps;
00403 }
00404 polypoints[pi].x = boxes[bi].UR.x;
00405 polypoints[pi++].y = boxes[bi].LL.y;
00406 polypoints[pi].x = boxes[bi].UR.x;
00407 polypoints[pi++].y = boxes[bi].UR.y;
00408 polypoints[pi].x = boxes[bi].LL.x;
00409 polypoints[pi++].y = boxes[bi].UR.y;
00410 polypoints[pi].x = boxes[bi].LL.x;
00411 polypoints[pi++].y = boxes[bi].LL.y;
00412 }
00413 }
00414 }
00415 else {
00416 #ifdef OBSOLETE
00417
00418
00419
00420
00421
00422
00423
00424
00425 point p0, p1;
00426 box b0, b1;
00427 b0 = pp->boxes[0];
00428 b1 = pp->boxes[1];
00429
00430 if (b0.UR.x == b1.LL.x) {
00431 p0 = b0.LL;
00432 p1 = mkpt(b0.LL.x, b0.UR.y);
00433 } else if (b0.LL.y == b1.UR.y) {
00434 p0 = mkpt(b0.LL.x, b0.UR.y);
00435 p1 = b0.UR;
00436 } else if (b0.LL.x == b1.UR.x) {
00437 p0 = b0.UR;
00438 p1 = mkpt(b0.UR.x, b0.LL.y);
00439 } else if (b0.UR.y == b1.LL.y) {
00440 p0 = mkpt(b0.UR.x, b0.LL.y);
00441 p1 = b0.LL;
00442 } else
00443 abort();
00444 pi = append(pp, 0, p0, p1, 0);
00445 #else
00446 abort();
00447 #endif
00448 }
00449
00450 if (flip) {
00451 int i;
00452 for (bi = 0; bi < boxn; bi++) {
00453 int v = boxes[bi].UR.y;
00454 boxes[bi].UR.y = -1*boxes[bi].LL.y;
00455 boxes[bi].LL.y = -v;
00456 }
00457 for (i = 0; i < pi; i++)
00458 polypoints[i].y *= -1;
00459 }
00460
00461 for (bi = 0; bi < boxn; bi++)
00462 boxes[bi].LL.x = INT_MAX, boxes[bi].UR.x = INT_MIN;
00463 poly.ps = polypoints, poly.pn = pi;
00464 eps[0].x = pp->start.p.x, eps[0].y = pp->start.p.y;
00465 eps[1].x = pp->end.p.x, eps[1].y = pp->end.p.y;
00466 if (Pshortestpath(&poly, eps, &pl) == -1)
00467 abort();
00468 #ifdef DEBUG
00469 if (debugleveln(realedge, 3)) {
00470 psprintpoly(poly);
00471 psprintline(pl);
00472 }
00473 #endif
00474
00475 if (polyline) {
00476 make_polyline (pl, &spl);
00477 }
00478 else {
00479 if (poly.pn > edgen) {
00480 edges = ALLOC(poly.pn, edges, Pedge_t);
00481 edgen = poly.pn;
00482 }
00483 for (edgei = 0; edgei < poly.pn; edgei++) {
00484 edges[edgei].a = polypoints[edgei];
00485 edges[edgei].b = polypoints[(edgei + 1) % poly.pn];
00486 }
00487 if (pp->start.constrained) {
00488 evs[0].x = cos(pp->start.theta);
00489 evs[0].y = sin(pp->start.theta);
00490 } else
00491 evs[0].x = evs[0].y = 0;
00492 if (pp->end.constrained) {
00493 evs[1].x = -cos(pp->end.theta);
00494 evs[1].y = -sin(pp->end.theta);
00495 } else
00496 evs[1].x = evs[1].y = 0;
00497
00498 if (Proutespline(edges, poly.pn, pl, evs, &spl) == -1)
00499 abort();
00500 #ifdef DEBUG
00501 if (debugleveln(realedge, 3)) {
00502 psprintspline(spl);
00503 psprintinit(0);
00504 }
00505 #endif
00506 }
00507 mkspacep(spl.pn);
00508 for (bi = 0; bi < boxn; bi++) {
00509 boxes[bi].LL.x = INT_MAX;
00510 boxes[bi].UR.x = INT_MIN;
00511 }
00512 for (splinepi = 0; splinepi < spl.pn; splinepi++) {
00513 ps[splinepi].x = spl.ps[splinepi].x;
00514 ps[splinepi].y = spl.ps[splinepi].y;
00515 }
00516 REDO:
00517 for (splinepi = 0; splinepi + 3 < spl.pn; splinepi += 3) {
00518 int num_div = delta * boxn;
00519 for (si = 0; si <= num_div; si++) {
00520 t = si / ((double)num_div);
00521 sp[0] = ps[splinepi];
00522 sp[1] = ps[splinepi + 1];
00523 sp[2] = ps[splinepi + 2];
00524 sp[3] = ps[splinepi + 3];
00525 sp[0].x = sp[0].x + t * (sp[1].x - sp[0].x);
00526 sp[0].y = sp[0].y + t * (sp[1].y - sp[0].y);
00527 sp[1].x = sp[1].x + t * (sp[2].x - sp[1].x);
00528 sp[1].y = sp[1].y + t * (sp[2].y - sp[1].y);
00529 sp[2].x = sp[2].x + t * (sp[3].x - sp[2].x);
00530 sp[2].y = sp[2].y + t * (sp[3].y - sp[2].y);
00531 sp[0].x = sp[0].x + t * (sp[1].x - sp[0].x);
00532 sp[0].y = sp[0].y + t * (sp[1].y - sp[0].y);
00533 sp[1].x = sp[1].x + t * (sp[2].x - sp[1].x);
00534 sp[1].y = sp[1].y + t * (sp[2].y - sp[1].y);
00535 sp[0].x = sp[0].x + t * (sp[1].x - sp[0].x);
00536 sp[0].y = sp[0].y + t * (sp[1].y - sp[0].y);
00537 for (bi = 0; bi < boxn; bi++) {
00538 if (sp[0].y <= boxes[bi].UR.y && sp[0].y >= boxes[bi].LL.y) {
00539 if (boxes[bi].LL.x > sp[0].x)
00540 boxes[bi].LL.x = sp[0].x;
00541 if (boxes[bi].UR.x < sp[0].x)
00542 boxes[bi].UR.x = sp[0].x;
00543 }
00544 }
00545 }
00546 }
00547
00548
00549
00550
00551
00552 for (bi = 0; bi < boxn; bi++) {
00553 if ((boxes[bi].LL.x == INT_MAX) || (boxes[bi].UR.x == INT_MIN)) {
00554 delta *= 2;
00555 goto REDO;
00556 }
00557 }
00558 *npoints = spl.pn;
00559
00560 #ifdef DEBUG
00561 if (GD_showboxes(realedge->head->graph) == 2 ||
00562 GD_showboxes(realedge->tail->graph) == 2 ||
00563 ED_showboxes(realedge) == 2 ||
00564 ND_showboxes(realedge->head) == 2 ||
00565 ND_showboxes(realedge->tail) == 2)
00566 printboxes(boxn, boxes);
00567 #endif
00568
00569 return ps;
00570 }
00571
00572 point *routesplines(path * pp, int *npoints)
00573 {
00574 return _routesplines (pp, npoints, 0);
00575 }
00576
00577 point *routepolylines(path * pp, int *npoints)
00578 {
00579 return _routesplines (pp, npoints, 1);
00580 }
00581
00582 static int overlap(int i0, int i1, int j0, int j1)
00583 {
00584
00585 if (i1 <= j0)
00586 return 0;
00587 if (i0 >= j1)
00588 return 0;
00589 if ((j0 <= i0) && (i0 <= j1))
00590 return (j1 - i0);
00591 if ((j0 <= i1) && (i1 <= j1))
00592 return (i1 - j0);
00593 return MIN(i1 - i0, j1 - j0);
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 static void checkpath(int boxn, box* boxes, path* thepath)
00605 {
00606 box *ba, *bb;
00607 int bi, i, errs, l, r, d, u;
00608 int xoverlap, yoverlap;
00609
00610 #ifndef DONTFIXPATH
00611
00612 i = 0;
00613 for (bi = 0; bi < boxn; bi++) {
00614 if (boxes[bi].LL.y == boxes[bi].UR.y)
00615 continue;
00616 if (boxes[bi].LL.x == boxes[bi].UR.x)
00617 continue;
00618 if (i != bi)
00619 boxes[i] = boxes[bi];
00620 i++;
00621 }
00622 boxn = i;
00623 #endif
00624
00625 ba = &boxes[0];
00626 if (ba->LL.x > ba->UR.x || ba->LL.y > ba->UR.y) {
00627 agerr(AGERR, "in checkpath, box 0 has LL coord > UR coord\n");
00628 printpath(thepath);
00629 abort();
00630 }
00631 for (bi = 0; bi < boxn - 1; bi++) {
00632 ba = &boxes[bi], bb = &boxes[bi + 1];
00633 if (bb->LL.x > bb->UR.x || bb->LL.y > bb->UR.y) {
00634 agerr(AGERR, "in checkpath, box %d has LL coord > UR coord\n",
00635 bi + 1);
00636 printpath(thepath);
00637 abort();
00638 }
00639 l = (ba->UR.x < bb->LL.x) ? 1 : 0;
00640 r = (ba->LL.x > bb->UR.x) ? 1 : 0;
00641 d = (ba->UR.y < bb->LL.y) ? 1 : 0;
00642 u = (ba->LL.y > bb->UR.y) ? 1 : 0;
00643 errs = l + r + d + u;
00644 if (errs > 0 && Verbose) {
00645 fprintf(stderr, "in checkpath, boxes %d and %d don't touch\n",
00646 bi, bi + 1);
00647 printpath(thepath);
00648 }
00649 #ifndef DONTFIXPATH
00650 if (errs > 0) {
00651 int xy;
00652
00653 if (l == 1)
00654 xy = ba->UR.x, ba->UR.x = bb->LL.x, bb->LL.x = xy, l = 0;
00655 else if (r == 1)
00656 xy = ba->LL.x, ba->LL.x = bb->UR.x, bb->UR.x = xy, r = 0;
00657 else if (d == 1)
00658 xy = ba->UR.y, ba->UR.y = bb->LL.y, bb->LL.y = xy, d = 0;
00659 else if (u == 1)
00660 xy = ba->LL.y, ba->LL.y = bb->UR.y, bb->UR.y = xy, u = 0;
00661 for (i = 0; i < errs - 1; i++) {
00662 if (l == 1)
00663 xy = (ba->UR.x + bb->LL.x) / 2.0 + 0.5, ba->UR.x =
00664 bb->LL.x = xy, l = 0;
00665 else if (r == 1)
00666 xy = (ba->LL.x + bb->UR.x) / 2.0 + 0.5, ba->LL.x =
00667 bb->UR.x = xy, r = 0;
00668 else if (d == 1)
00669 xy = (ba->UR.y + bb->LL.y) / 2.0 + 0.5, ba->UR.y =
00670 bb->LL.y = xy, d = 0;
00671 else if (u == 1)
00672 xy = (ba->LL.y + bb->UR.y) / 2.0 + 0.5, ba->LL.y =
00673 bb->UR.y = xy, u = 0;
00674 }
00675 }
00676 #else
00677 abort();
00678 #endif
00679 #ifndef DONTFIXPATH
00680
00681 xoverlap = overlap(ba->LL.x, ba->UR.x, bb->LL.x, bb->UR.x);
00682 yoverlap = overlap(ba->LL.y, ba->UR.y, bb->LL.y, bb->UR.y);
00683 if (xoverlap && yoverlap) {
00684 if (xoverlap < yoverlap) {
00685 if (ba->UR.x - ba->LL.x > bb->UR.x - bb->LL.x) {
00686
00687 if (ba->UR.x < bb->UR.x)
00688 ba->UR.x = bb->LL.x;
00689 else
00690 ba->LL.x = bb->UR.x;
00691 } else {
00692
00693 if (ba->UR.x < bb->UR.x)
00694 bb->LL.x = ba->UR.x;
00695 else
00696 bb->UR.x = ba->LL.x;
00697 }
00698 } else {
00699 if (ba->UR.y - ba->LL.y > bb->UR.y - bb->LL.y) {
00700
00701 if (ba->UR.y < bb->UR.y)
00702 ba->UR.y = bb->LL.y;
00703 else
00704 ba->LL.y = bb->UR.y;
00705 } else {
00706
00707 if (ba->UR.y < bb->UR.y)
00708 bb->LL.y = ba->UR.y;
00709 else
00710 bb->UR.y = ba->LL.y;
00711 }
00712 }
00713 }
00714 }
00715 #endif
00716
00717 if (thepath->start.p.x < boxes[0].LL.x
00718 || thepath->start.p.x > boxes[0].UR.x
00719 || thepath->start.p.y < boxes[0].LL.y
00720 || thepath->start.p.y > boxes[0].UR.y) {
00721 if (Verbose) {
00722 fprintf(stderr, "in checkpath, start port not in first box\n");
00723 printpath(thepath);
00724 }
00725 #ifndef DONTFIXPATH
00726 if (thepath->start.p.x < boxes[0].LL.x)
00727 thepath->start.p.x = boxes[0].LL.x;
00728 if (thepath->start.p.x > boxes[0].UR.x)
00729 thepath->start.p.x = boxes[0].UR.x;
00730 if (thepath->start.p.y < boxes[0].LL.y)
00731 thepath->start.p.y = boxes[0].LL.y;
00732 if (thepath->start.p.y > boxes[0].UR.y)
00733 thepath->start.p.y = boxes[0].UR.y;
00734 #else
00735 abort();
00736 #endif
00737 }
00738 if (thepath->end.p.x < boxes[boxn - 1].LL.x
00739 || thepath->end.p.x > boxes[boxn - 1].UR.x
00740 || thepath->end.p.y < boxes[boxn - 1].LL.y
00741 || thepath->end.p.y > boxes[boxn - 1].UR.y) {
00742 if (Verbose) {
00743 fprintf(stderr, "in checkpath, end port not in last box\n");
00744 printpath(thepath);
00745 }
00746 #ifndef DONTFIXPATH
00747 if (thepath->end.p.x < boxes[boxn - 1].LL.x)
00748 thepath->end.p.x = boxes[boxn - 1].LL.x;
00749 if (thepath->end.p.x > boxes[boxn - 1].UR.x)
00750 thepath->end.p.x = boxes[boxn - 1].UR.x;
00751 if (thepath->end.p.y < boxes[boxn - 1].LL.y)
00752 thepath->end.p.y = boxes[boxn - 1].LL.y;
00753 if (thepath->end.p.y > boxes[boxn - 1].UR.y)
00754 thepath->end.p.y = boxes[boxn - 1].UR.y;
00755 #else
00756 abort();
00757 #endif
00758 }
00759 }
00760
00761 static void mkspacep(int size)
00762 {
00763 if (size > maxpn) {
00764 int newmax = maxpn + (size / PINC + 1) * PINC;
00765 ps = RALLOC(newmax, ps, point);
00766 maxpn = newmax;
00767 }
00768 }
00769
00770 #ifdef OBSOLETE
00771
00772
00773
00774
00775
00776 #define BOXLEFT 0
00777 #define BOXTOP 1
00778 #define BOXRIGHT 2
00779 #define BOXBOTTOM 3
00780 static box B;
00781
00782 static int sideofB(point p, box B)
00783 {
00784 if (p.x == B.LL.x)
00785 return BOXLEFT;
00786 if (p.y == B.UR.y)
00787 return BOXTOP;
00788 if (p.x == B.UR.x)
00789 return BOXRIGHT;
00790 if (p.y == B.LL.y)
00791 return BOXBOTTOM;
00792 abort();
00793 return 0;
00794 }
00795
00796 static int appendpt(point p, int polysz)
00797 {
00798 polypoints[polysz].x = p.x;
00799 polypoints[polysz].y = p.y;
00800 return (polysz+1);
00801 }
00802
00803 static int cmpf(const void *pp0, const void *pp1)
00804 {
00805 point p0, p1;
00806 int s0, s1;
00807
00808 p0 = *(point *) pp0;
00809 p1 = *(point *) pp1;
00810 s0 = sideofB(p0, B);
00811 s1 = sideofB(p1, B);
00812
00813 if (s0 != s1)
00814 return s1 - s0;
00815 switch (s0) {
00816 case BOXLEFT:
00817 return p1.y - p0.y;
00818 case BOXTOP:
00819 return p1.x - p0.x;
00820 case BOXRIGHT:
00821 return p0.y - p1.y;
00822 case BOXBOTTOM:
00823 return p0.x - p1.x;
00824 default:
00825 abort();
00826 }
00827 return 0;
00828 }
00829
00830
00831
00832 static int
00833 append(path * path, int bi, point p0, point p1, int polysz)
00834 {
00835 point v[8];
00836 point w[8];
00837 box b = path->boxes[bi];
00838 box bb;
00839 int i, i0, npw, delta;
00840 point q0 = { 0, 0 }, q1 = { 0, 0}, r;
00841 int pn;
00842
00843
00844 pn = 0;
00845 v[pn++] = b.LL;
00846 v[pn++] = mkpt(b.UR.x, b.LL.y);
00847 v[pn++] = b.UR;
00848 v[pn++] = mkpt(b.LL.x, b.UR.y);
00849 v[pn++] = p0;
00850 v[pn++] = p1;
00851
00852 if (bi + 1 < path->nbox) {
00853 bb = path->boxes[bi + 1];
00854
00855 if (b.UR.x == bb.LL.x) {
00856 q0.x = q1.x = b.UR.x;
00857 q0.y = MIN(b.UR.y, bb.UR.y);
00858 q1.y = MAX(b.LL.y, bb.LL.y);
00859 } else if (b.LL.x == bb.UR.x) {
00860 q0.x = q1.x = b.LL.x;
00861 q0.y = MIN(b.UR.y, bb.UR.y);
00862 q1.y = MAX(b.LL.y, bb.LL.y);
00863 } else if (b.UR.y == bb.LL.y) {
00864 q0.y = q1.y = b.UR.y;
00865 q0.x = MIN(b.UR.x, bb.UR.x);
00866 q1.x = MAX(b.LL.x, bb.LL.x);
00867 } else if (b.LL.y == bb.UR.y) {
00868 q0.y = q1.y = b.LL.y;
00869 q0.x = MIN(b.UR.x, bb.UR.x);
00870 q1.x = MAX(b.LL.x, bb.LL.x);
00871 } else
00872 abort();
00873 v[pn++] = q0;
00874 v[pn++] = q1;
00875 }
00876
00877
00878 B = b;
00879 qsort(v, pn, sizeof(v[0]), cmpf);
00880
00881
00882 w[0] = v[0];
00883 npw = 1;
00884 i0 = -1;
00885 for (i = 0; i < pn; i++) {
00886 if (pteq(w[npw - 1], p0))
00887 i0 = npw - 1;
00888 if (!pteq(v[i], w[npw - 1]))
00889 w[npw++] = v[i];
00890 }
00891
00892 i = i0;
00893 if (bi == 0)
00894 polysz = appendpt(p0, polysz);
00895 if (pteq(p1, w[(i0 + 1) % npw]))
00896 delta = -1;
00897 else if (pteq(p1, w[(i0 - 1 + npw) % npw]))
00898 delta = 1;
00899 else
00900 abort();
00901 do {
00902 i = (i + delta + npw) % npw;
00903 r = w[i];
00904
00905
00906 if ((bi == 0) || (!pteq(r, p0) && !pteq(r, p1)))
00907 polysz = appendpt(r, polysz);
00908 if (pteq(r, p1))
00909 break;
00910 if (bi + 1 < path->nbox) {
00911 if (pteq(r, q0)) {
00912 polysz = append(path, bi + 1, q0, q1, polysz);
00913 polysz = appendpt(q1, polysz);
00914 i += delta;
00915 } else if (pteq(r, q1)) {
00916 polysz = append(path, bi + 1, q1, q0, polysz);
00917 polysz = appendpt(q0, polysz);
00918 i += delta;
00919 }
00920 }
00921 } while (i != i0);
00922 return polysz;
00923 }
00924 #endif
00925
00926 static void printpath(path * pp)
00927 {
00928 int bi;
00929
00930 #ifdef NOTNOW
00931 fprintf(stderr, "edge %d from %s to %s\n", nedges,
00932 realedge->tail->name, realedge->head->name);
00933 if (ED_count(origedge) > 1)
00934 fprintf(stderr, " (it's part of a concentrator edge)\n");
00935 #endif
00936 fprintf(stderr, "%d boxes:\n", pp->nbox);
00937 for (bi = 0; bi < pp->nbox; bi++)
00938 fprintf(stderr, "%d (%d, %d), (%d, %d)\n", bi, pp->boxes[bi].LL.x,
00939 pp->boxes[bi].LL.y, pp->boxes[bi].UR.x,
00940 pp->boxes[bi].UR.y);
00941 fprintf(stderr, "start port: (%d, %d), tangent angle: %.3f, %s\n",
00942 pp->start.p.x, pp->start.p.y, pp->start.theta,
00943 pp->start.constrained ? "constrained" : "not constrained");
00944 fprintf(stderr, "end port: (%d, %d), tangent angle: %.3f, %s\n",
00945 pp->end.p.x, pp->end.p.y, pp->end.theta,
00946 pp->end.constrained ? "constrained" : "not constrained");
00947 }
00948