コード例 #1
0
ファイル: neatosplines.c プロジェクト: hsorby/graphviz
/* getPath
 * Construct the shortest path from one endpoint of e to the other.
 * The obstacles and their number are given by obs and npoly.
 * vconfig is a precomputed data structure to help in the computation.
 * If chkPts is true, the function finds the polygons, if any, containing
 * the endpoints and tells the shortest path computation to ignore them. 
 * Assumes this info is set in ND_lim, usually from _spline_edges.
 * Returns the shortest path.
 */
Ppolyline_t
getPath(edge_t * e, vconfig_t * vconfig, int chkPts, Ppoly_t ** obs,
	int npoly)
{
    Ppolyline_t line;
    int pp, qp;
    Ppoint_t p, q;

    p = add_pointf(ND_coord(agtail(e)), ED_tail_port(e).p);
    q = add_pointf(ND_coord(aghead(e)), ED_head_port(e).p);

    /* determine the polygons (if any) that contain the endpoints */
    pp = qp = POLYID_NONE;
    if (chkPts) {
	pp = ND_lim(agtail(e));
	qp = ND_lim(aghead(e));
/*
	for (i = 0; i < npoly; i++) {
	    if ((pp == POLYID_NONE) && in_poly(*obs[i], p))
		pp = i;
	    if ((qp == POLYID_NONE) && in_poly(*obs[i], q))
		qp = i;
	}
*/
    }
    Pobspath(vconfig, p, pp, q, qp, &line);
    return line;
}
コード例 #2
0
/* makeStraightEdge:
 *
 * FIX: handle ports on boundary?
 */
void 
makeStraightEdge(graph_t * g, edge_t * e, int et, splineInfo* sinfo)
{
    pointf dumb[4];
    node_t *n = agtail(e);
    node_t *head = aghead(e);
    int e_cnt = ED_count(e);
    int curved = (et == ET_CURVED);
    pointf perp;
    pointf del;
    edge_t *e0;
    int i, j, xstep, dx;
    double l_perp;
    pointf dumber[4];
    pointf p, q;

    p = dumb[1] = dumb[0] = add_pointf(ND_coord(n), ED_tail_port(e).p);
    q = dumb[2] = dumb[3] = add_pointf(ND_coord(head), ED_head_port(e).p);
    if ((e_cnt == 1) || Concentrate) {
	if (curved) bend(dumb,get_centroid(g));
	clip_and_install(e, aghead(e), dumb, 4, sinfo);
	addEdgeLabels(g, e, p, q);
	return;
    }

    e0 = e;
    if (APPROXEQPT(dumb[0], dumb[3], MILLIPOINT)) {
	/* degenerate case */
	dumb[1] = dumb[0];
	dumb[2] = dumb[3];
	del.x = 0;
	del.y = 0;
    }
    else {
        perp.x = dumb[0].y - dumb[3].y;
        perp.y = dumb[3].x - dumb[0].x;
	l_perp = LEN(perp.x, perp.y);
	xstep = GD_nodesep(g->root);
	dx = xstep * (e_cnt - 1) / 2;
	dumb[1].x = dumb[0].x + (dx * perp.x) / l_perp;
	dumb[1].y = dumb[0].y + (dx * perp.y) / l_perp;
	dumb[2].x = dumb[3].x + (dx * perp.x) / l_perp;
	dumb[2].y = dumb[3].y + (dx * perp.y) / l_perp;
	del.x = -xstep * perp.x / l_perp;
	del.y = -xstep * perp.y / l_perp;
    }

    for (i = 0; i < e_cnt; i++) {
	if (aghead(e0) == head) {
	    p = dumb[0];
	    q = dumb[3];
	    for (j = 0; j < 4; j++) {
		dumber[j] = dumb[j];
	    }
	} else {
	    p = dumb[3];
	    q = dumb[0];
	    for (j = 0; j < 4; j++) {
		dumber[3 - j] = dumb[j];
	    }
	}
	if (et == ET_PLINE) {
	    Ppoint_t pts[4];
	    Ppolyline_t spl, line;

	    line.pn = 4;
	    line.ps = pts;
	    for (j=0; j < 4; j++) {
		pts[j] = dumber[j];
	    }
	    make_polyline (line, &spl);
	    clip_and_install(e0, aghead(e0), spl.ps, spl.pn, sinfo);
	}
	else
	    clip_and_install(e0, aghead(e0), dumber, 4, sinfo);

	addEdgeLabels(g, e0, p, q);
	e0 = ED_to_virt(e0);
	dumb[1].x += del.x;
	dumb[1].y += del.y;
	dumb[2].x += del.x;
	dumb[2].y += del.y;
    }
}
コード例 #3
0
ファイル: utils.c プロジェクト: jho1965us/graphviz
/* compute_bb:
 * Compute bounding box of g using nodes, splines, and clusters.
 * Assumes bb of clusters already computed.
 * store in GD_bb.
 */
void compute_bb(graph_t * g)
{
    node_t *n;
    edge_t *e;
    boxf b, bb;
    boxf BF;
    pointf ptf, s2;
    int i, j;

    if ((agnnodes(g) == 0) && (GD_n_cluster(g) ==0)) {
	bb.LL = pointfof(0, 0);
	bb.UR = pointfof(0, 0);
	return;
    }

    bb.LL = pointfof(INT_MAX, INT_MAX);
    bb.UR = pointfof(-INT_MAX, -INT_MAX);
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	ptf = coord(n);
	s2.x = ND_xsize(n) / 2.0;
	s2.y = ND_ysize(n) / 2.0;
	b.LL = sub_pointf(ptf, s2);
	b.UR = add_pointf(ptf, s2);

	EXPANDBB(bb,b);
	if (ND_xlabel(n) && ND_xlabel(n)->set) {
	    bb = addLabelBB(bb, ND_xlabel(n), GD_flip(g));
	}
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
	    if (ED_spl(e) == 0)
		continue;
	    for (i = 0; i < ED_spl(e)->size; i++) {
		for (j = 0; j < (((Agedgeinfo_t*)AGDATA(e))->spl)->list[i].size; j++) {
		    ptf = ED_spl(e)->list[i].list[j];
		    EXPANDBP(bb,ptf);
		}
	    }
	    if (ED_label(e) && ED_label(e)->set) {
		bb = addLabelBB(bb, ED_label(e), GD_flip(g));
	    }
	    if (ED_head_label(e) && ED_head_label(e)->set) {
		bb = addLabelBB(bb, ED_head_label(e), GD_flip(g));
	    }
	    if (ED_tail_label(e) && ED_tail_label(e)->set) {
		bb = addLabelBB(bb, ED_tail_label(e), GD_flip(g));
	    }
	    if (ED_xlabel(e) && ED_xlabel(e)->set) {
		bb = addLabelBB(bb, ED_xlabel(e), GD_flip(g));
	    }
	}
    }

    for (i = 1; i <= GD_n_cluster(g); i++) {
	B2BF(GD_bb(GD_clust(g)[i]), BF);
	EXPANDBB(bb,BF);
    }
    if (GD_label(g) && GD_label(g)->set) {
	bb = addLabelBB(bb, GD_label(g), GD_flip(g));
    }

    GD_bb(g) = bb;
}
コード例 #4
0
/* addEndpoint:
 * Add node to graph representing spline end point p inside obstruction obs_id.
 * For each side of obstruction, add edge from p to corresponding triangle.
 * The node id of the new node in the graph is v_id.
 * If p lies on the side of its node (sides != 0), we limit the triangles
 * to those within 45 degrees of each side of the natural direction of p.
 */
static void addEndpoint(router_t * rtr, pointf p, node_t* v, int v_id, int sides)
{
    int obs_id = ND_lim(v);
    int starti = rtr->obs[obs_id];
    int endi = rtr->obs[obs_id + 1];
    pointf* pts = rtr->ps;
    int i, t;
    double d;
    pointf vr, v0, v1;

    switch (sides) {
    case TOP :
	vr = add_pointf (p, north);
	v0 = add_pointf (p, northwest);
	v1 = add_pointf (p, northeast);
	break;
    case TOP|RIGHT :
	vr = add_pointf (p, northeast);
	v0 = add_pointf (p, north);
	v1 = add_pointf (p, east);
	break;
    case RIGHT :
	vr = add_pointf (p, east);
	v0 = add_pointf (p, northeast);
	v1 = add_pointf (p, southeast);
	break;
    case BOTTOM|RIGHT :
	vr = add_pointf (p, southeast);
	v0 = add_pointf (p, east);
	v1 = add_pointf (p, south);
	break;
    case BOTTOM :
	vr = add_pointf (p, south);
	v0 = add_pointf (p, southeast);
	v1 = add_pointf (p, southwest);
	break;
    case BOTTOM|LEFT :
	vr = add_pointf (p, southwest);
	v0 = add_pointf (p, south);
	v1 = add_pointf (p, west);
	break;
    case LEFT :
	vr = add_pointf (p, west);
	v0 = add_pointf (p, southwest);
	v1 = add_pointf (p, northwest);
	break;
    case TOP|LEFT :
	vr = add_pointf (p, northwest);
	v0 = add_pointf (p, west);
	v1 = add_pointf (p, north);
	break;
    case 0 :
	break;
    default :
	assert (0);
	break;
    }

    rtr->tg->nodes[v_id].ne = 0;
    rtr->tg->nodes[v_id].ctr = p;
    for (i = starti; i < endi; i++) {
	ipair seg;
	seg.i = i;
	if (i < endi - 1)
	    seg.j = i + 1;
	else
	    seg.j = starti;
	t = findMap(rtr->trimap, seg.i, seg.j);
	if (sides && !inCone (v0, p, v1, pts[seg.i]) && !inCone (v0, p, v1, pts[seg.j]) && !raySeg(p,vr,pts[seg.i],pts[seg.j]))
	    continue;
	d = DIST(p, (rtr->tg->nodes + t)->ctr);
	addTriEdge(rtr->tg, v_id, t, d, seg);
    }
}