33 static int nedges, nboxes;
40 static int polypointn;
44 static int checkpath(
int,
boxf*,
path*);
45 static int mkspacep(
int size);
46 static void printpath(
path * pp);
48 static void printboxes(
int boxn,
boxf* boxes)
56 for (bi = 0; bi < boxn; bi++) {
57 ll = boxes[bi].
LL, ur = boxes[bi].
UR;
58 sprintf(buf,
"%d %d %d %d pathbox", (
int)ll.
x, (
int)ll.
y, (
int)ur.
x, (
int)ur.
y);
66 static void psprintpolypts(
Ppoint_t * p,
int sz)
70 fprintf(stderr,
"%%!\n");
71 fprintf(stderr,
"%% constraint poly\n");
72 fprintf(stderr,
"newpath\n");
73 for (i = 0; i < sz; i++)
74 fprintf(stderr,
"%f %f %s\n", p[i].x, p[i].y,
75 (i == 0 ?
"moveto" :
"lineto"));
76 fprintf(stderr,
"closepath stroke\n");
78 static void psprintpoint(
point p)
80 fprintf(stderr,
"gsave\n");
82 "newpath %d %d moveto %d %d 2 0 360 arc closepath fill stroke\n",
84 fprintf(stderr,
"/Times-Roman findfont 4 scalefont setfont\n");
85 fprintf(stderr,
"%d %d moveto (\\(%d,%d\\)) show\n", p.
x + 5, p.
y + 5,
87 fprintf(stderr,
"grestore\n");
89 static void psprintpointf(
pointf p)
91 fprintf(stderr,
"gsave\n");
93 "newpath %.5g %.5g moveto %.5g %.5g 2 0 360 arc closepath fill stroke\n",
95 fprintf(stderr,
"/Times-Roman findfont 4 scalefont setfont\n");
96 fprintf(stderr,
"%.5g %.5g moveto (\\(%.5g,%.5g\\)) show\n", p.
x + 5, p.
y + 5,
98 fprintf(stderr,
"grestore\n");
112 Show_boxes[li++] = strdup (
"gsave 1 0 0 setrgbcolor newpath");
113 for (i = 0; i < spl.
pn; i++) {
114 sprintf(buf,
"%f %f %s", spl.
ps[i].
x, spl.
ps[i].
y,
115 (i == 0) ?
"moveto" : ((i % 3 == 0) ?
"curveto" :
""));
118 Show_boxes[li++] = strdup (
"stroke grestore");
133 Show_boxes[li++] = strdup (
"gsave 0 0 1 setrgbcolor newpath");
134 for (i = 0; i < pl.
pn; i++) {
135 sprintf(buf,
"%f %f %s", pl.
ps[i].
x, pl.
ps[i].
y,
136 (i == 0 ?
"moveto" :
"lineto"));
139 Show_boxes[li++] = strdup (
"stroke grestore");
144 static void psprintpoly(
Ppoly_t p)
155 Show_boxes[li++] = strdup (
"gsave 0 1 0 setrgbcolor");
156 for (bi = 0; bi < p.
pn; bi++) {
158 tl.
y = (
int)p.
ps[bi].
y;
161 if ((tl.
x == hd.
x) && (tl.
y == hd.
y)) pfx =
"%%";
163 sprintf(buf,
"%s%d %d %d %d makevec", pfx, tl.
x, tl.
y, hd.
x, hd.
y);
172 static void psprintboxes(
int boxn,
boxf* boxes)
182 Show_boxes[li++] = strdup (
"gsave 0 1 0 setrgbcolor");
183 for (bi = 0; bi < boxn; bi++) {
184 ll = boxes[bi].
LL, ur = boxes[bi].
UR;
185 sprintf(buf,
"newpath\n%d %d moveto", (
int)ll.
x, (
int)ll.
y);
187 sprintf(buf,
"%d %d lineto", (
int)ll.
x, (
int)ur.
y);
189 sprintf(buf,
"%d %d lineto", (
int)ur.
x, (
int)ur.
y);
191 sprintf(buf,
"%d %d lineto", (
int)ur.
x, (
int)ll.
y);
193 Show_boxes[li++] = strdup (
"closepath stroke");
201 static void psprintinit (
int begin)
214 static int debugleveln(
edge_t* realedge,
int i)
248 if (poly.
pn > edgen) {
252 for (i = 0; i < poly.
pn; i++) {
253 edges[i].
a = poly.
ps[i];
254 edges[i].
b = poly.
ps[(i + 1) % poly.
pn];
257 if (pp->start.constrained) {
258 evs[0].
x = cos(pp->start.theta);
259 evs[0].
y = sin(pp->start.theta);
262 evs[0].
x = evs[0].
y = 0;
264 if (pp->end.constrained) {
265 evs[1].
x = -cos(pp->end.theta);
266 evs[1].
y = -sin(pp->end.theta);
269 evs[1].
x = evs[1].
y = 0;
274 if (mkspacep(spl.
pn))
276 for (i = 0; i < spl.
pn; i++) {
290 if (++routeinit > 1)
return 0;
292 agerr(
AGERR,
"routesplinesinit: cannot allocate ps\n");
315 if (--routeinit > 0)
return;
318 free(bs), bs =
NULL ;
322 "routesplines: %d edges, %d boxes %.2f sec\n",
327 limitBoxes (
boxf* boxes,
int boxn,
pointf *pps,
int pn,
int delta)
329 int bi, si, splinepi;
332 int num_div = delta * boxn;
334 for (splinepi = 0; splinepi + 3 < pn; splinepi += 3) {
335 for (si = 0; si <= num_div; si++) {
336 t = si / (double)num_div;
337 sp[0] = pps[splinepi];
338 sp[1] = pps[splinepi + 1];
339 sp[2] = pps[splinepi + 2];
340 sp[3] = pps[splinepi + 3];
341 sp[0].
x = sp[0].
x + t * (sp[1].
x - sp[0].
x);
342 sp[0].
y = sp[0].
y + t * (sp[1].
y - sp[0].
y);
343 sp[1].
x = sp[1].
x + t * (sp[2].
x - sp[1].
x);
344 sp[1].
y = sp[1].
y + t * (sp[2].
y - sp[1].
y);
345 sp[2].
x = sp[2].
x + t * (sp[3].
x - sp[2].
x);
346 sp[2].
y = sp[2].
y + t * (sp[3].
y - sp[2].
y);
347 sp[0].
x = sp[0].
x + t * (sp[1].
x - sp[0].
x);
348 sp[0].
y = sp[0].
y + t * (sp[1].
y - sp[0].
y);
349 sp[1].
x = sp[1].
x + t * (sp[2].
x - sp[1].
x);
350 sp[1].
y = sp[1].
y + t * (sp[2].
y - sp[1].
y);
351 sp[0].
x = sp[0].
x + t * (sp[1].
x - sp[0].
x);
352 sp[0].
y = sp[0].
y + t * (sp[1].
y - sp[0].
y);
353 for (bi = 0; bi < boxn; bi++) {
357 if (sp[0].y <= boxes[bi].UR.y+
FUDGE && sp[0].
y >= boxes[bi].
LL.
y-
FUDGE) {
358 if (boxes[bi].LL.x > sp[0].
x)
359 boxes[bi].
LL.
x = sp[0].
x;
360 if (boxes[bi].UR.x < sp[0].
x)
361 boxes[bi].
UR.
x = sp[0].
x;
368 #define INIT_DELTA 10
369 #define LOOP_TRIES 15
390 static pointf *_routesplines(
path * pp,
int *npoints,
int polyline)
397 int edgei, prev, next;
416 agerr(
AGERR,
"in routesplines, cannot find NORMAL edge\n");
423 if (checkpath(boxn, boxes, pp))
427 if (debugleveln(realedge, 1))
428 printboxes(boxn, boxes);
429 if (debugleveln(realedge, 3)) {
431 psprintboxes(boxn, boxes);
435 if (boxn * 8 > polypointn) {
437 polypointn = boxn * 8;
440 if ((boxn > 1) && (boxes[0].LL.y > boxes[1].
LL.
y)) {
442 for (bi = 0; bi < boxn; bi++) {
443 double v = boxes[bi].
UR.
y;
444 boxes[bi].
UR.
y = -1*boxes[bi].
LL.
y;
453 for (bi = 0, pi = 0; bi < boxn; bi++) {
456 prev = (boxes[bi].
LL.
y > boxes[bi - 1].
LL.
y) ? -1 : 1;
458 next = (boxes[bi + 1].
LL.
y > boxes[bi].
LL.
y) ? 1 : -1;
460 if (next == -1 || prev == 1) {
461 polypoints[pi].
x = boxes[bi].
LL.
x;
462 polypoints[pi++].
y = boxes[bi].
UR.
y;
463 polypoints[pi].
x = boxes[bi].
LL.
x;
464 polypoints[pi++].
y = boxes[bi].
LL.
y;
466 polypoints[pi].
x = boxes[bi].
UR.
x;
467 polypoints[pi++].
y = boxes[bi].
LL.
y;
468 polypoints[pi].
x = boxes[bi].
UR.
x;
469 polypoints[pi++].
y = boxes[bi].
UR.
y;
472 else if (prev == 0) {
473 polypoints[pi].
x = boxes[bi].
LL.
x;
474 polypoints[pi++].
y = boxes[bi].
UR.
y;
475 polypoints[pi].
x = boxes[bi].
LL.
x;
476 polypoints[pi++].
y = boxes[bi].
LL.
y;
479 if (!(prev == -1 && next == -1)) {
480 agerr(
AGERR,
"in routesplines, illegal values of prev %d and next %d, line %d\n", prev, next, __LINE__);
485 for (bi = boxn - 1; bi >= 0; bi--) {
488 prev = (boxes[bi].
LL.
y > boxes[bi + 1].
LL.
y) ? -1 : 1;
490 next = (boxes[bi - 1].
LL.
y > boxes[bi].
LL.
y) ? 1 : -1;
492 if (next == -1 || prev == 1 ) {
493 polypoints[pi].
x = boxes[bi].
LL.
x;
494 polypoints[pi++].
y = boxes[bi].
UR.
y;
495 polypoints[pi].
x = boxes[bi].
LL.
x;
496 polypoints[pi++].
y = boxes[bi].
LL.
y;
498 polypoints[pi].
x = boxes[bi].
UR.
x;
499 polypoints[pi++].
y = boxes[bi].
LL.
y;
500 polypoints[pi].
x = boxes[bi].
UR.
x;
501 polypoints[pi++].
y = boxes[bi].
UR.
y;
504 else if (prev == 0) {
505 polypoints[pi].
x = boxes[bi].
UR.
x;
506 polypoints[pi++].
y = boxes[bi].
LL.
y;
507 polypoints[pi].
x = boxes[bi].
UR.
x;
508 polypoints[pi++].
y = boxes[bi].
UR.
y;
511 if (!(prev == -1 && next == -1)) {
513 agerr(
AGERR,
"in routesplines, illegal values of prev %d and next %d, line %d\n", prev, next, __LINE__);
516 polypoints[pi].
x = boxes[bi].
UR.
x;
517 polypoints[pi++].
y = boxes[bi].
LL.
y;
518 polypoints[pi].
x = boxes[bi].
UR.
x;
519 polypoints[pi++].
y = boxes[bi].
UR.
y;
520 polypoints[pi].
x = boxes[bi].
LL.
x;
521 polypoints[pi++].
y = boxes[bi].
UR.
y;
522 polypoints[pi].
x = boxes[bi].
LL.
x;
523 polypoints[pi++].
y = boxes[bi].
LL.
y;
534 for (bi = 0; bi < boxn; bi++) {
535 double v = boxes[bi].
UR.
y;
536 boxes[bi].
UR.
y = -1*boxes[bi].
LL.
y;
539 for (i = 0; i < pi; i++)
540 polypoints[i].y *= -1;
543 for (bi = 0; bi < boxn; bi++)
545 poly.
ps = polypoints, poly.
pn = pi;
549 agerr(
AGERR,
"in routesplines, Pshortestpath failed\n");
553 if (debugleveln(realedge, 3)) {
563 if (poly.
pn > edgen) {
567 for (edgei = 0; edgei < poly.
pn; edgei++) {
568 edges[edgei].
a = polypoints[edgei];
569 edges[edgei].
b = polypoints[(edgei + 1) % poly.
pn];
575 evs[0].
x = evs[0].
y = 0;
580 evs[1].
x = evs[1].
y = 0;
583 agerr(
AGERR,
"in routesplines, Proutespline failed\n");
587 if (debugleveln(realedge, 3)) {
593 if (mkspacep(spl.
pn))
596 for (bi = 0; bi < boxn; bi++) {
601 for (splinepi = 0; splinepi < spl.
pn; splinepi++) {
602 ps[splinepi] = spl.
ps[splinepi];
605 for (loopcnt = 0; unbounded && (loopcnt <
LOOP_TRIES); loopcnt++) {
606 limitBoxes (boxes, boxn, ps, spl.
pn, delta);
613 for (bi = 0; bi < boxn; bi++) {
647 printboxes(boxn, boxes);
655 return _routesplines (pp, npoints, 0);
660 return _routesplines (pp, npoints, 1);
663 static int overlap(
int i0,
int i1,
int j0,
int j1)
670 if ((j0 <= i0) && (i0 <= j1))
672 if ((j0 <= i1) && (i1 <= j1))
674 return MIN(i1 - i0, j1 - j0);
687 static int checkpath(
int boxn,
boxf* boxes,
path* thepath)
690 int bi, i, errs, l, r, d, u;
691 int xoverlap, yoverlap;
696 for (bi = 0; bi < boxn; bi++) {
697 if (
ABS(boxes[bi].LL.y - boxes[bi].
UR.
y) < .01)
699 if (
ABS(boxes[bi].LL.x - boxes[bi].
UR.
x) < .01)
702 boxes[i] = boxes[bi];
710 agerr(
AGERR,
"in checkpath, box 0 has LL coord > UR coord\n");
714 for (bi = 0; bi < boxn - 1; bi++) {
715 ba = &boxes[bi], bb = &boxes[bi + 1];
716 if (bb->LL.x > bb->UR.x || bb->LL.y > bb->UR.y) {
717 agerr(
AGERR,
"in checkpath, box %d has LL coord > UR coord\n",
722 l = (ba->
UR.
x < bb->LL.x) ? 1 : 0;
723 r = (ba->
LL.
x > bb->UR.x) ? 1 : 0;
724 d = (ba->
UR.
y < bb->LL.y) ? 1 : 0;
725 u = (ba->
LL.
y > bb->UR.y) ? 1 : 0;
726 errs = l + r + d + u;
728 fprintf(stderr,
"in checkpath, boxes %d and %d don't touch\n",
737 xy = ba->
UR.
x, ba->
UR.
x = bb->LL.x, bb->LL.x = xy, l = 0;
739 xy = ba->
LL.
x, ba->
LL.
x = bb->UR.x, bb->UR.x = xy, r = 0;
741 xy = ba->
UR.
y, ba->
UR.
y = bb->LL.y, bb->LL.y = xy, d = 0;
743 xy = ba->
LL.
y, ba->
LL.
y = bb->UR.y, bb->UR.y = xy, u = 0;
744 for (i = 0; i < errs - 1; i++) {
746 xy = (ba->
UR.
x + bb->LL.x) / 2.0 + 0.5, ba->
UR.
x =
747 bb->LL.x = xy, l = 0;
749 xy = (ba->
LL.
x + bb->UR.x) / 2.0 + 0.5, ba->
LL.
x =
750 bb->UR.x = xy, r = 0;
752 xy = (ba->
UR.
y + bb->LL.y) / 2.0 + 0.5, ba->
UR.
y =
753 bb->LL.y = xy, d = 0;
755 xy = (ba->
LL.
y + bb->UR.y) / 2.0 + 0.5, ba->
LL.
y =
756 bb->UR.y = xy, u = 0;
766 if (xoverlap && yoverlap) {
767 if (xoverlap < yoverlap) {
768 if (ba->
UR.
x - ba->
LL.
x > bb->UR.x - bb->LL.x) {
770 if (ba->
UR.
x < bb->UR.x)
776 if (ba->
UR.
x < bb->UR.x)
782 if (ba->
UR.
y - ba->
LL.
y > bb->UR.y - bb->LL.y) {
784 if (ba->
UR.
y < bb->UR.y)
790 if (ba->
UR.
y < bb->UR.y)
805 fprintf(stderr,
"in checkpath, start port not in first box\n");
821 if (thepath->
end.
p.
x < boxes[boxn - 1].
LL.
x
822 || thepath->
end.
p.
x > boxes[boxn - 1].
UR.
x
823 || thepath->
end.
p.
y < boxes[boxn - 1].
LL.
y
824 || thepath->
end.
p.
y > boxes[boxn - 1].
UR.
y) {
826 fprintf(stderr,
"in checkpath, end port not in last box\n");
830 if (thepath->
end.
p.
x < boxes[boxn - 1].
LL.
x)
831 thepath->
end.
p.
x = boxes[boxn - 1].
LL.
x;
832 if (thepath->
end.
p.
x > boxes[boxn - 1].
UR.
x)
833 thepath->
end.
p.
x = boxes[boxn - 1].
UR.
x;
834 if (thepath->
end.
p.
y < boxes[boxn - 1].
LL.
y)
835 thepath->
end.
p.
y = boxes[boxn - 1].
LL.
y;
836 if (thepath->
end.
p.
y > boxes[boxn - 1].
UR.
y)
837 thepath->
end.
p.
y = boxes[boxn - 1].
UR.
y;
845 static int mkspacep(
int size)
848 int newmax = maxpn + (size /
PINC + 1) *
PINC;
859 static void printpath(
path * pp)
864 fprintf(stderr,
"edge %d from %s to %s\n", nedges,
865 realedge->tail->name, realedge->head->name);
867 fprintf(stderr,
" (it's part of a concentrator edge)\n");
869 fprintf(stderr,
"%d boxes:\n", pp->
nbox);
870 for (bi = 0; bi < pp->
nbox; bi++)
871 fprintf(stderr,
"%d (%.5g, %.5g), (%.5g, %.5g)\n", bi,
874 fprintf(stderr,
"start port: (%.5g, %.5g), tangent angle: %.5g, %s\n",
877 fprintf(stderr,
"end port: (%.5g, %.5g), tangent angle: %.5g, %s\n",
885 static pointf sum = {0.0, 0.0};
893 if (save == g)
return sum;
911 midpt.
x = (spl[0].
x + spl[3].
x)/2.0;
912 midpt.
y = (spl[0].
y + spl[3].
y)/2.0;
913 dx = (spl[3].
x - spl[0].
x);
914 dy = (spl[3].
y - spl[0].
y);
915 dist = sqrt(dx*dx + dy*dy);
918 double vX = centroid.
x - midpt.
x;
919 double vY = centroid.
y - midpt.
y;
920 double magV = sqrt(vX*vX + vY*vY);
921 if (magV == 0)
return;
922 a.
x = midpt.
x - vX / magV * r;
923 a.
y = midpt.
y - vY / magV * r;
926 spl[1].
x = spl[2].
x = a.
x;
927 spl[1].
y = spl[2].
y = a.
y;
952 for (i = 0; i < e_cnt; i++) {
983 if (curved) bend(dumb,get_centroid(g));
998 perp.
x = dumb[0].
y - dumb[3].
y;
999 perp.
y = dumb[3].
x - dumb[0].
x;
1000 l_perp =
LEN(perp.
x, perp.
y);
1002 dx = xstep * (e_cnt - 1) / 2;
1003 dumb[1].
x = dumb[0].
x + (dx * perp.
x) / l_perp;
1004 dumb[1].
y = dumb[0].
y + (dx * perp.
y) / l_perp;
1005 dumb[2].
x = dumb[3].
x + (dx * perp.
x) / l_perp;
1006 dumb[2].
y = dumb[3].
y + (dx * perp.
y) / l_perp;
1007 del.
x = -xstep * perp.
x / l_perp;
1008 del.
y = -xstep * perp.
y / l_perp;
1011 for (i = 0; i < e_cnt; i++) {
1016 for (j = 0; j < 4; j++) {
1017 dumber[j] = dumb[j];
1022 for (j = 0; j < 4; j++) {
1023 dumber[3 - j] = dumb[j];
1032 for (j=0; j < 4; j++) {
pointf * routesplines(path *, int *)
#define RALLOC(size, ptr, type)
pointf * routepolylines(path *pp, int *npoints)
#define ALLOC(size, ptr, type)
int Proutespline(Pedge_t *barriers, int n_barriers, Ppolyline_t input_route, Pvector_t endpoint_slopes[2], Ppolyline_t *output_route)
void makeStraightEdges(graph_t *g, edge_t **edges, int e_cnt, int et, splineInfo *sinfo)
void make_polyline(Ppolyline_t line, Ppolyline_t *sline)
void clip_and_install(edge_t *fe, node_t *hn, pointf *ps, int pn, splineInfo *info)
#define APPROXEQPT(p, q, tol)
int agerr(agerrlevel_t level, const char *fmt,...)
pointf * simpleSplineRoute(pointf, pointf, Ppoly_t, int *, int)
int routesplinesinit(void)
CGRAPH_API Agraph_t * agraphof(void *obj)
CGRAPH_API Agnode_t * agtail(Agedge_t *e)
void addEdgeLabels(graph_t *g, edge_t *e, pointf rp, pointf rq)
CGRAPH_API Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
CGRAPH_API Agnode_t * aghead(Agedge_t *e)
void routesplinesterm(void)
CGRAPH_API char * agnameof(void *)
CGRAPH_API Agnode_t * agfstnode(Agraph_t *g)
if(aagss+aagstacksize-1<=aagssp)
EXTERN unsigned char Concentrate
EXTERN unsigned char Verbose
int Pshortestpath(Ppoly_t *boundary, Ppoint_t endpoints[2], Ppolyline_t *output_route)
void makeStraightEdge(graph_t *g, edge_t *e, int edgetype, splineInfo *info)
EXTERN char ** Show_boxes
double dist(Site *s, Site *t)