int shortPath (sgraph* g, snode* from, snode* to) { snode* n; sedge* e; snode* adjn; int d; int x, y; for (x = 0; x<g->nnodes; x++) { snode* temp; temp = &(g->nodes[x]); N_VAL(temp) = UNSEEN; } PQinit(); if (PQ_insert (from)) return 1; N_DAD(from) = NULL; N_VAL(from) = 0; while ((n = PQremove())) { #ifdef DEBUG fprintf (stderr, "process %d\n", n->index); #endif N_VAL(n) *= -1; if (n == to) break; for (y=0; y<n->n_adj; y++) { e = &(g->edges[n->adj_edge_list[y]]); adjn = adjacentNode(g, e, n); if (N_VAL(adjn) < 0) { d = -(N_VAL(n) + E_WT(e)); if (N_VAL(adjn) == UNSEEN) { #ifdef DEBUG fprintf (stderr, "new %d (%d)\n", adjn->index, -d); #endif N_VAL(adjn) = d; if (PQ_insert(adjn)) return 1; N_DAD(adjn) = n; N_EDGE(adjn) = e; } else { if (N_VAL(adjn) < d) { #ifdef DEBUG fprintf (stderr, "adjust %d (%d)\n", adjn->index, -d); #endif PQupdate(adjn, d); N_DAD(adjn) = n; N_EDGE(adjn) = e; } } } } } /* PQfree(); */ return 0; }
static route convertSPtoRoute (sgraph* g, snode* fst, snode* lst) { route rte; snode* ptr; snode* next; snode* prev; /* node in shortest path just previous to next */ int i, sz = 0; cell* cp; cell* ncp; segment seg; double fix, b1, b2; int l1, l2; pointf bp1, bp2, prevbp; /* bend points */ /* count no. of nodes in shortest path */ for (ptr = fst; ptr; ptr = N_DAD(ptr)) sz++; rte.n = 0; rte.segs = N_NEW(sz-2, segment); /* at most sz-2 segments */ seg.prev = seg.next = 0; ptr = prev = N_DAD(fst); next = N_DAD(ptr); if (IsNode(ptr->cells[0])) cp = ptr->cells[1]; else cp = ptr->cells[0]; bp1 = sidePt (ptr, cp); while (N_DAD(next)!=NULL) { ncp = cellOf (prev, next); updateWts (g, ncp, N_EDGE(ptr)); /* add seg if path bends or at end */ if ((ptr->isVert != next->isVert) || (N_DAD(next) == lst)) { if (ptr->isVert != next->isVert) bp2 = midPt (ncp); else bp2 = sidePt(next, ncp); if (ptr->isVert) { /* horizontal segment */ if (ptr == N_DAD(fst)) l1 = B_NODE; else if (prevbp.y > bp1.y) l1 = B_UP; else l1 = B_DOWN; if (ptr->isVert != next->isVert) { if (next->cells[0] == ncp) l2 = B_UP; else l2 = B_DOWN; } else l2 = B_NODE; fix = cp->bb.LL.y; b1 = cp->bb.LL.x; b2 = ncp->bb.LL.x; } else { /* vertical segment */ if (ptr == N_DAD(fst)) l1 = B_NODE; else if (prevbp.x > bp1.x) l1 = B_RIGHT; else l1 = B_LEFT; if (ptr->isVert != next->isVert) { if (next->cells[0] == ncp) l2 = B_RIGHT; else l2 = B_LEFT; } else l2 = B_NODE; fix = cp->bb.LL.x; b1 = cp->bb.LL.y; b2 = ncp->bb.LL.y; } setSeg (&seg, !ptr->isVert, fix, b1, b2, l1, l2); rte.segs[rte.n++] = seg; cp = ncp; prevbp = bp1; bp1 = bp2; if ((ptr->isVert != next->isVert) && (N_DAD(next) == lst)) { bp2 = sidePt(next, ncp); l2 = B_NODE; if (next->isVert) { /* horizontal segment */ if (prevbp.y > bp1.y) l1 = B_UP; else l1 = B_DOWN; fix = cp->bb.LL.y; b1 = cp->bb.LL.x; b2 = ncp->bb.LL.x; } else { if (prevbp.x > bp1.x) l1 = B_RIGHT; else l1 = B_LEFT; fix = cp->bb.LL.x; b1 = cp->bb.LL.y; b2 = ncp->bb.LL.y; } setSeg (&seg, !next->isVert, fix, b1, b2, l1, l2); rte.segs[rte.n++] = seg; } ptr = next; } prev = next; next = N_DAD(next); } rte.segs = realloc (rte.segs, rte.n*sizeof(segment)); for (i=0; i<rte.n; i++) { if (i > 0) rte.segs[i].prev = rte.segs + (i-1); if (i < rte.n-1) rte.segs[i].next = rte.segs + (i+1); } return rte; }