55#define CELL(n) ((cell*)ND_alg(n))
57static double MID(
double a,
double b) {
68 if (cp == q->
cells[0] || cp == q->
cells[1])
return cp;
81 if (cp == ptr.
cells[1]) {
99setSeg (
segment* sp,
bool dir,
double fix,
double b1,
double b2,
int l1,
int l2)
135 pointf bp1, prevbp = {0.0,0.0};
156 else if (prevbp.
y > bp1.
y) l1 =
B_UP;
188 if (prevbp.
y > bp1.
y) l1 =
B_UP;
212 for (
size_t i = 0; i < ret.
n; i++) {
251 const paird *key1 = k1;
252 const paird *key2 = k2;
253 if (key1->
p1 > key2->
p1) {
254 if (key1->
p2 <= key2->
p2)
return 0;
257 if (key1->
p1 < key2->
p1) {
258 if (key1->
p2 >= key2->
p2)
return 0;
265 const double *key1 = k1;
266 const double *key2 = k2;
267 return fcmp(*key1, *key2);
310 for (
size_t i = 0; i < mp->
ncells; i++) {
346 for (
size_t i = 0; i < mp->
ncells; i++) {
399 for (
size_t i=0;i<nrtes;i++) {
400 route rte = route_list[i];
401 for (
size_t j=0;j<rte.
n;j++) {
419 for (
size_t i = 0; i < cp->
nsides; i++) {
422 if (onp->
isVert)
continue;
423 const bool onTop = onp->
cells[0] == cp;
439 for (
size_t i = 0; i < cp->
nsides; i++) {
477 fprintf (fp,
"((%f,%f),(%f,%f)) %s %s", seg->
comm_coord, seg->
p.
p1,
480 fprintf (fp,
"((%f,%f),(%f,%f)) %s %s", seg->
p.
p1,seg->
comm_coord,
486 fprintf (stderr,
"channel %.0f (%f,%f)\n", v, cp->
p.
p1, cp->
p.
p2);
491 fputs (
" ->\n", stderr);
492 for (
size_t i = 0; i <
LIST_SIZE(&adj); ++i) {
495 fputs (
"\n", stderr);
544 if ((S1l2==T2 && S2l2!=T2) || (S1l2==
B_NODE && S2l2==T1))
554 if (S1->
l2 == T1 && S2->
l1 == T2)
return -1;
555 if (S1->
l2 == T2 && S2->
l1 == T1)
return 1;
558 if (S1->
p.
p2 > S2->
p.
p2) {
559 if (S2->
l1 == T2 && S2->
l2 == T2)
return -1;
560 if (S2->
l1 == T1 && S2->
l2 == T1)
return 1;
571 if (S1l2==
T)
return -1;
581 if (S1->
p.
p2 < S2->
p.
p1 || S1->
p.
p1 > S2->
p.
p2)
return 0;
588 if (S1->
p.
p1 == S2->
p.
p1) {
589 if (S1->
p.
p2 < S2->
p.
p2) {
594 if (S1->
p.
p2 > S2->
p.
p2) {
599 if (S1->
l1 == S2->
l1 && S1->
l2 == S2->
l2)
601 if (S2->
l1 == S2->
l2) {
602 if (S2->
l1 == T1)
return 1;
603 if (S2->
l1 == T2)
return -1;
604 if (S1->
l1 != T1 && S1->
l2 != T1)
return 1;
605 if (S1->
l1 != T2 && S1->
l2 != T2)
return -1;
608 if (S2->
l1 == T1 && S2->
l2 == T2) {
609 if (S1->
l1 != T1 && S1->
l2 == T2)
return 1;
610 if (S1->
l1 == T1 && S1->
l2 != T2)
return -1;
613 if (S2->
l2 == T1 && S2->
l1 == T2) {
614 if (S1->
l2 != T1 && S1->
l1 == T2)
return 1;
615 if (S1->
l2 == T1 && S1->
l1 != T2)
return -1;
630 if (S1->
p.
p2 == S2->
p.
p1) {
631 if (S1->
l2 == S2->
l1)
return 0;
632 if (S1->
l2 == T2)
return 1;
636 if (S1->
l1 == S2->
l2)
return 0;
637 if (S1->
l1 == T2)
return 1;
660 agerrorf(
"incomparable segments !! -- Aborting\n");
672 seg_list_t *seg_list = &cp->
seg_list;
676 for (
size_t x = 0; x + 1 < size; ++x) {
677 for (
size_t y = x + 1; y < size; ++y) {
681 }
else if (
cmp > 0) {
683 }
else if (
cmp == -1) {
731 for(x=1;x<=hops;x++) {
735 if(current->
l1==
B_UP) ans *= -1;
758 return s1->p.p1 == s2->
p.
p1 &&
759 s1->p.p2 == s2->
p.
p2 &&
772 int prec = 0, ans = 0, temp;
819 for (x=1;x<=hops;x++) {
940 else if (
LIST_GET(segs, j)->prev == 0) {
944 if (
LIST_GET(segs, i)->prev->comm_coord ==
945 LIST_GET(segs, j)->prev->comm_coord)
971 }
else if (prec1 == 0) {
977 }
else if (prec2 == 0) {
981 1 - dir, hops.
b, mp);
982 }
else if (prec2 == 1) {
986 1 - dir, hops.
b, mp);
988 }
else if (prec1 == 1) {
1063 return round(lo + f * (hi - lo));
1071 for (
size_t irte = 0; irte < n_edges; irte++) {
1076 route rte = route_list[irte];
1077 size_t npts = 1 + 3*rte.
n;
1094 for (
size_t i = 1;i<rte.
n;i++) {
1129 return (
int)
DIST2(p,q);
1135 if (e0->
d > e1->
d) {
1138 if (e0->
d < e1->
d) {
1173 char*
s =
agget(g,
"odb");
1176 if (
s && *
s !=
'\0') {
1177 while ((c = *
s++)) {
1202 agwarningf(
"Orthogonal edges do not currently handle edge labels. Try using xlabels.\n");
1238 const int gstart = sg->
nnodes;
1242 for (
size_t i = 0; i < n_edges; i++) {
1259 if (
shortPath (sg, dn, sn))
goto orthofinish;
1281 for (
size_t i=0; i < n_edges; i++)
1282 free (route_list[i].segs);
1293%%%%BoundingBox: (atend)\n\
1298 X Y 3 0 360 arc fill\n\
1317 newpath l d moveto\n\
1318 r d lineto r u lineto l u lineto\n\
1326%%%%BoundingBox: %.f %.f %.f %.f\n";
1341 agerrorf(
"Node not adjacent to cell -- Aborting\n");
1359 bb.
LL.
x = fmin(bb.
LL.
x, x);
1360 bb.
LL.
y = fmin(bb.
LL.
y, y);
1361 bb.
UR.
x = fmax(bb.
UR.
x, x);
1362 bb.
UR.
y = fmax(bb.
UR.
y, y);
1363 fprintf(fp,
"newpath %.0f %.0f moveto\n", x, y);
1365 for (
size_t i = 1;i<rte.
n;i++) {
1373 bb.
LL.
x = fmin(bb.
LL.
x, x);
1374 bb.
LL.
y = fmin(bb.
LL.
y, y);
1375 bb.
UR.
x = fmax(bb.
UR.
x, x);
1376 bb.
UR.
y = fmax(bb.
UR.
y, y);
1377 fprintf(fp,
"%.0f %.0f lineto\n", x, y);
1389 bb.
LL.
x = fmin(bb.
LL.
x, x);
1390 bb.
LL.
y = fmin(bb.
LL.
y, y);
1391 bb.
UR.
x = fmax(bb.
UR.
x, x);
1392 bb.
UR.
y = fmax(bb.
UR.
y, y);
1393 fprintf(fp,
"%.0f %.0f lineto stroke\n", x, y);
1410 fputs (
"graph G {\n", fp);
1411 fputs (
" node[shape=point]\n", fp);
1412 fputs (
" layout=neato\n", fp);
1413 for (
int i = 0; i < sg->
nnodes; i++) {
1416 if (cp == np->
cells[1]) {
1423 fprintf (fp,
" %d [pos=\"%.0f,%.0f!\"]\n", i, p.
x, p.
y);
1425 for (
int i = 0; i < sg->
nedges; i++) {
1427 fprintf (fp,
" %d -- %d[label=\"%f\"]\n", ep->
v1, ep->
v2, ep->
weight);
1434 boxf absbb = {.
LL = {.
x = DBL_MAX, .y = DBL_MAX},
1435 .UR = {.x = -DBL_MAX, .y = -DBL_MAX}};
1438 fprintf (fp,
"%d %d translate\n",
TRANS,
TRANS);
1440 fputs (
"0 0 1 setrgbcolor\n", fp);
1441 for (
size_t i = 0; i < mp->
ngcells; i++) {
1443 fprintf (fp,
"%f %f %f %f node\n", bb.
LL.
x, bb.
LL.
y, bb.
UR.
x, bb.
UR.
y);
1446 for (
size_t i = 0; i < n_edges; i++) {
1447 absbb =
emitEdge (fp, es[i].e, route_list[i], mp, absbb);
1450 fputs (
"0.8 0.8 0.8 setrgbcolor\n", fp);
1451 for (
size_t i = 0; i < mp->
ncells; i++) {
1453 fprintf (fp,
"%f %f %f %f cell\n", bb.
LL.
x, bb.
LL.
y, bb.
UR.
x, bb.
UR.
y);
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
CDT_API Dtlink_t * dtflatten(Dt_t *)
CDT_API int dtclose(Dt_t *)
CDT_API Dtmethod_t * Dtoset
ordered set (self-adjusting tree)
CDT_API Dt_t * dtopen(Dtdisc_t *, Dtmethod_t *)
static NORETURN void graphviz_exit(int status)
static int cmp(const void *key, const void *candidate)
geometric functions (e.g. on points and boxes)
static WUR pointf mid_pointf(pointf p, pointf q)
static WUR pointf add_pointf(pointf p, pointf q)
static WUR pointf interpolate_pointf(double t, pointf p, pointf q)
static void free_graph(gmlgraph *p)
int agnedges(Agraph_t *g)
char * agget(void *obj, char *name)
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
void agwarningf(const char *fmt,...)
void agerrorf(const char *fmt,...)
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Agnode_t * agfstnode(Agraph_t *g)
char * agnameof(void *)
returns a string descriptor for the object.
Arithmetic helper functions.
static int fcmp(double a, double b)
comparator for doubles
type-generic dynamically expanding list
#define LIST_DETACH(list, datap, sizep)
#define LIST_APPEND(list, item)
#define LIST_RESERVE(list, capacity)
#define LIST_IS_EMPTY(list)
#define LIST_GET(list, index)
maze * mkMaze(graph_t *g)
creates maze and fills maze::gcells and maze::cells. A subroutine of orthoEdges.
void updateWts(sgraph *g, cell *cp, sedge *ep)
updates sedge::weight of cell edges
makes maze with mkMaze for routing orthogonal edges
#define IsHScan(cp)
cell already inserted in horizontal channel
#define IsVScan(cp)
cell already inserted in vertical channel
#define IsNode(cp)
cell corresponds to node
static boxf bbox(Ppoly_t **obsp, int npoly, int *np)
NEATOPROCS_API void s1(graph_t *, node_t *)
snode priority queue for shortPath in sgraph
static char * bendToStr(bend b)
static int seg_cmp(segment *S1, segment *S2)
static pointf sidePt(const snode ptr, const cell *cp)
static route convertSPtoRoute(sgraph *g, snode *fst, snode *lst)
static Dt_t * extractVChans(maze *mp)
static int add_edges_in_G(channel *cp)
static int decide_point(pair *ret, segment *si, segment *sj, int dir1, int dir2)
static int add_p_edges(Dt_t *chans, maze *mp)
static int edgeLen(Agedge_t *e)
static void removeEdge(segment *seg1, segment *seg2, int dir, maze *mp)
static void setSeg(segment *sp, bool dir, double fix, double b1, double b2, int l1, int l2)
static int eqEndSeg(bend S1l2, bend S2l2, bend T1, bend T2)
static double htrack(segment *seg, maze *m)
static pointf coordOf(cell *cp, snode *np)
static UNUSED void emitGraph(FILE *fp, maze *mp, size_t n_edges, route *route_list, epair_t[])
static void putSeg(FILE *fp, segment *seg)
static UNUSED void emitSearchGraph(FILE *fp, sgraph *sg)
dumps in dot format snode::cells and edges of sgraph for debugging
static int segCmp(segment *S1, segment *S2, bend T1, bend T2)
static bool swap_ends_p(edge_t *e)
static segment * next_seg(segment *seg, int dir)
static void set_parallel_edges(segment *seg1, segment *seg2, int dir1, int dir2, int hops, maze *mp)
static bool spline_merge(node_t *n)
static int addPEdges(channel *cp, maze *mp)
static double MID(double a, double b)
static UNUSED void dumpChanG(channel *cp, double v)
static void assignSegs(size_t nrtes, route *route_list, maze *mp)
static cell * cellOf(snode *p, snode *q)
static void create_graphs(Dt_t *chans)
static void addChan(Dt_t *chdict, channel *cp, double j)
static pointf midPt(const cell *cp)
static int add_np_edges(Dt_t *chans)
static void insertChan(channel *chan, segment *seg)
static double vtrack(segment *seg, maze *m)
static Dt_t * extractHChans(maze *mp)
static int overlapSeg(segment *S1, segment *S2, bend T1, bend T2)
static void freeChannel(void *chan)
static void assignTrackNo(Dt_t *chans)
static void attachOrthoEdges(maze *mp, size_t n_edges, route *route_list, splineInfo *sinfo, epair_t es[], bool doLbls)
void orthoEdges(Agraph_t *g, bool useLbls)
static int dcmpid(void *k1, void *k2)
static int ellSeg(bend S1l1, bend S1l2, bend T)
static void freeChanItem(void *item)
static int chancmpid(void *k1, void *k2)
static void addNodeEdges(sgraph *sg, cell *cp, snode *np)
static int assignTracks(maze *mp)
static int propagate_prec(segment *seg, int prec, int hops, int dir)
static channel * chanSearch(Dt_t *chans, segment *seg)
static void addLoop(sgraph *sg, cell *cp, snode *dp, snode *sp)
static int edgecmp(const void *x, const void *y)
static boxf emitEdge(FILE *fp, Agedge_t *e, route rte, maze *m, boxf bb)
static bool is_parallel(segment *s1, segment *s2)
static Dtdisc_t chanItemDisc
void addPS(PointSet *ps, double x, double y)
void freePS(PointSet *ps)
int isInPS(PointSet *ps, double x, double y)
point containers PointSet and PointMap
rawgraph * make_graph(size_t n)
makes a graph with n vertices, 0 edges
void insert_edge(rawgraph *g, size_t v1, size_t v2)
inserts edge FROM v1 to v2
void remove_redge(rawgraph *g, size_t v1, size_t v2)
removes any edge between v1 to v2 – irrespective of direction
void top_sort(rawgraph *g)
bool edge_exists(rawgraph *g, size_t v1, size_t v2)
tests if there is an edge FROM v1 TO v2
void clip_and_install(edge_t *fe, node_t *hn, pointf *ps, size_t pn, splineInfo *info)
void addEdgeLabels(edge_t *e)
sedge * createSEdge(sgraph *g, snode *v1, snode *v2, double wt)
int shortPath(sgraph *g, snode *from, snode *to)
result of partitioning available space, part of maze
snode ** sides
up to four sides: M_RIGHT, M_TOP, M_LEFT, M_BOTTOM
seg_list_t seg_list
segment pointers
available channels for orthogonal edges around nodes of graph_t
cell * cells
cells not corresponding to graph nodes
cell * gcells
cells corresponding to graph nodes
Dt_t * vchans
set of vertical channels, created by extractVChans
Dt_t * hchans
set of horizontal channels, created by extractHChans.
size_t ind_no
index number of this segment in its channel
a node of search graph sgraph, is created as a border segment between two adjusted cells of type cell...
struct cell * cells[2]
[0] - left or botom, [1] - top or right adjusted cell
adj_list_t adj_list
adjacency list
abstraction for squashing compiler warnings for unused symbols