예제 #1
0
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;
}
예제 #2
0
파일: ortho.c 프로젝트: TidyHuang/vizgems
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;
}