static void vrml_begin_node(GVJ_t *job) { FILE *out = job->output_file; obj_state_t *obj = job->obj; node_t *n = obj->u.n; double z = obj->z; int width, height; int transparent; fprintf(out, "# node %s\n", n->name); if (z < MinZ) MinZ = z; if (shapeOf(n) != SH_POINT) { PNGfile = nodefile(job->output_filename, n); width = (ND_lw_i(n) + ND_rw_i(n)) * Scale + 2 * NODE_PAD; height = (ND_ht_i(n) ) * Scale + 2 * NODE_PAD; im = gdImageCreate(width, height); /* make background transparent */ transparent = gdImageColorResolveAlpha(im, gdRedMax - 1, gdGreenMax, gdBlueMax, gdAlphaTransparent); gdImageColorTransparent(im, transparent); } }
void common_init_node(node_t * n) { struct fontinfo fi; char *str; ND_width(n) = late_double(n, N_width, DEFAULT_NODEWIDTH, MIN_NODEWIDTH); ND_height(n) = late_double(n, N_height, DEFAULT_NODEHEIGHT, MIN_NODEHEIGHT); ND_shape(n) = bind_shape(late_nnstring(n, N_shape, DEFAULT_NODESHAPE), n); str = agxget(n, N_label); fi.fontsize = late_double(n, N_fontsize, DEFAULT_FONTSIZE, MIN_FONTSIZE); fi.fontname = late_nnstring(n, N_fontname, DEFAULT_FONTNAME); fi.fontcolor = late_nnstring(n, N_fontcolor, DEFAULT_COLOR); ND_label(n) = make_label((void*)n, str, ((aghtmlstr(str) ? LT_HTML : LT_NONE) | ( (shapeOf(n) == SH_RECORD) ? LT_RECD : LT_NONE)), fi.fontsize, fi.fontname, fi.fontcolor); if (N_xlabel && (str = agxget(n, N_xlabel)) && (str[0])) { ND_xlabel(n) = make_label((void*)n, str, (aghtmlstr(str) ? LT_HTML : LT_NONE), fi.fontsize, fi.fontname, fi.fontcolor); GD_has_labels(agraphof(n)) |= NODE_XLABEL; } ND_showboxes(n) = late_int(n, N_showboxes, 0, 0); ND_shape(n)->fns->initfn(n); }
int makePoly(Poly * pp, Agnode_t * n, float xmargin, float ymargin) { int i; int sides; Point *verts; polygon_t *poly; boxf b; if (ND_clust(n)) { Point b; sides = 4; b.x = ND_width(n) / 2.0; b.y = ND_height(n) / 2.0; pp->kind = BOX; verts = N_GNEW(sides, Point); PUTPT(verts[0], b.x, b.y); PUTPT(verts[1], -b.x, b.y); PUTPT(verts[2], -b.x, -b.y); PUTPT(verts[3], b.x, -b.y); } else switch (shapeOf(n)) { case SH_POLY: poly = (polygon_t *) ND_shape_info(n); sides = poly->sides; if (sides >= 3) { /* real polygon */ verts = N_GNEW(sides, Point); for (i = 0; i < sides; i++) { verts[i].x = PS2INCH(poly->vertices[i].x); verts[i].y = PS2INCH(poly->vertices[i].y); } } else verts = genRound(n, &sides, 0, 0); if (streq(ND_shape(n)->name, "box")) pp->kind = BOX; else if (streq(ND_shape(n)->name, "polygon") && isBox(verts, sides)) pp->kind = BOX; else if ((poly->sides < 3) && poly->regular) pp->kind = CIRCLE; else pp->kind = 0; break; case SH_RECORD: sides = 4; verts = N_GNEW(sides, Point); b = ((field_t *) ND_shape_info(n))->b; verts[0] = makeScaledPoint(b.LL.x, b.LL.y); verts[1] = makeScaledPoint(b.UR.x, b.LL.y); verts[2] = makeScaledPoint(b.UR.x, b.UR.y); verts[3] = makeScaledPoint(b.LL.x, b.UR.y); pp->kind = BOX; break; case SH_POINT: pp->kind = CIRCLE; verts = genRound(n, &sides, 0, 0); break; default: agerr(AGERR, "makePoly: unknown shape type %s\n", ND_shape(n)->name); return 1; } #ifdef OLD if (margin != 0.0) inflatePts(verts, sides, margin); #else if ((xmargin != 1.0) || (ymargin != 1.0)) inflatePts(verts, sides, xmargin, ymargin); #endif pp->verts = verts; pp->nverts = sides; bbox(verts, sides, &pp->origin, &pp->corner); if (sides > maxcnt) maxcnt = sides; return 0; }
int makeAddPoly(Poly * pp, Agnode_t * n, float xmargin, float ymargin) { int i; int sides; Point *verts; polygon_t *poly; boxf b; if (ND_clust(n)) { Point b; sides = 4; b.x = ND_width(n) / 2.0 + xmargin; b.y = ND_height(n) / 2.0 + ymargin; pp->kind = BOX; verts = N_GNEW(sides, Point); PUTPT(verts[0], b.x, b.y); PUTPT(verts[1], -b.x, b.y); PUTPT(verts[2], -b.x, -b.y); PUTPT(verts[3], b.x, -b.y); } else switch (shapeOf(n)) { case SH_POLY: poly = (polygon_t *) ND_shape_info(n); sides = poly->sides; if (streq(ND_shape(n)->name, "box")) pp->kind = BOX; else if (streq(ND_shape(n)->name, "polygon") && isBox(poly->vertices, sides)) pp->kind = BOX; else if ((poly->sides < 3) && poly->regular) pp->kind = CIRCLE; else pp->kind = 0; if (sides >= 3) { /* real polygon */ verts = N_GNEW(sides, Point); if (pp->kind == BOX) { /* To do an additive margin, we rely on knowing that * the vertices are CCW starting from the UR */ verts[0].x = PS2INCH(poly->vertices[0].x) + xmargin; verts[0].y = PS2INCH(poly->vertices[0].y) + ymargin; verts[1].x = PS2INCH(poly->vertices[1].x) - xmargin; verts[1].y = PS2INCH(poly->vertices[1].y) + ymargin; verts[2].x = PS2INCH(poly->vertices[2].x) - xmargin; verts[2].y = PS2INCH(poly->vertices[2].y) - ymargin; verts[3].x = PS2INCH(poly->vertices[3].x) + xmargin; verts[3].y = PS2INCH(poly->vertices[3].y) - ymargin; } else { for (i = 0; i < sides; i++) { double h = LEN(poly->vertices[i].x,poly->vertices[i].y); verts[i].x = poly->vertices[i].x * (1.0 + xmargin/h); verts[i].y = poly->vertices[i].y * (1.0 + ymargin/h); verts[i].x = PS2INCH(verts[i].x); verts[i].y = PS2INCH(verts[i].y); } } } else verts = genRound(n, &sides, xmargin, ymargin); break; case SH_RECORD: sides = 4; verts = N_GNEW(sides, Point); b = ((field_t *) ND_shape_info(n))->b; verts[0] = makeScaledTransPoint(b.LL.x, b.LL.y, -xmargin, -ymargin); verts[1] = makeScaledTransPoint(b.UR.x, b.LL.y, xmargin, -ymargin); verts[2] = makeScaledTransPoint(b.UR.x, b.UR.y, xmargin, ymargin); verts[3] = makeScaledTransPoint(b.LL.x, b.UR.y, -xmargin, ymargin); pp->kind = BOX; break; case SH_POINT: pp->kind = CIRCLE; verts = genRound(n, &sides, xmargin, ymargin); break; default: agerr(AGERR, "makeAddPoly: unknown shape type %s\n", ND_shape(n)->name); return 1; } pp->verts = verts; pp->nverts = sides; bbox(verts, sides, &pp->origin, &pp->corner); if (sides > maxcnt) maxcnt = sides; return 0; }
/* makeObstacle: * Given a node, return an obstacle reflecting the * node's geometry. pmargin specifies how much space to allow * around the polygon. * Returns the constructed polygon on success, NULL on failure. * Failure means the node shape is not supported. * * If isOrtho is true, we have to use the bounding box of each node. * * The polygon has its vertices in CW order. * */ Ppoly_t *makeObstacle(node_t * n, expand_t* pmargin, boolean isOrtho) { Ppoly_t *obs; polygon_t *poly; double adj = 0.0; int j, sides; pointf polyp; boxf b; pointf pt; field_t *fld; epsf_t *desc; int isPoly; pointf* verts; pointf vs[4]; pointf p; pointf margin; switch (shapeOf(n)) { case SH_POLY: case SH_POINT: obs = NEW(Ppoly_t); poly = (polygon_t *) ND_shape_info(n); if (isOrtho) { isPoly = 1; sides = 4; verts = vs; margin.x = margin.y = 0; /* For fixedshape, we can't use the width and height, as this includes * the label. We only want to use the actual node shape. */ if (poly->option & FIXEDSHAPE) { b = polyBB (poly); vs[0] = b.LL; vs[1].x = b.UR.x; vs[1].y = b.LL.y; vs[2] = b.UR; vs[3].x = b.LL.x; vs[3].y = b.UR.y; } else { p.x = -ND_lw(n); p.y = -ND_ht(n)/2.0; vs[0] = p; p.x = ND_lw(n); vs[1] = p; p.y = ND_ht(n)/2.0; vs[2] = p; p.x = -ND_lw(n); vs[3] = p; } } else if (poly->sides >= 3) { isPoly = 1; sides = poly->sides; verts = poly->vertices; margin.x = pmargin->x; margin.y = pmargin->y; } else { /* ellipse */ isPoly = 0; sides = 8; adj = drand48() * .01; } obs->pn = sides; obs->ps = N_NEW(sides, Ppoint_t); /* assuming polys are in CCW order, and pathplan needs CW */ for (j = 0; j < sides; j++) { double xmargin = 0.0, ymargin = 0.0; if (isPoly) { if (pmargin->doAdd) { if (sides == 4) { switch (j) { case 0 : xmargin = margin.x; ymargin = margin.y; break; case 1 : xmargin = -margin.x; ymargin = margin.y; break; case 2 : xmargin = -margin.x; ymargin = -margin.y; break; case 3 : xmargin = margin.x; ymargin = -margin.y; break; } polyp.x = verts[j].x + xmargin; polyp.y = verts[j].y + ymargin; } else { double h = LEN(verts[j].x,verts[j].y); polyp.x = verts[j].x * (1.0 + margin.x/h); polyp.y = verts[j].y * (1.0 + margin.y/h); } } else { polyp.x = verts[j].x * margin.x; polyp.y = verts[j].y * margin.y; } } else { double c, s; c = cos(2.0 * M_PI * j / sides + adj); s = sin(2.0 * M_PI * j / sides + adj); if (pmargin->doAdd) { polyp.x = c*(ND_lw(n)+ND_rw(n)+pmargin->x) / 2.0; polyp.y = s*(ND_ht(n)+pmargin->y) / 2.0; } else { polyp.x = pmargin->x * c * (ND_lw(n) + ND_rw(n)) / 2.0; polyp.y = pmargin->y * s * ND_ht(n) / 2.0; } } obs->ps[sides - j - 1].x = polyp.x + ND_coord(n).x; obs->ps[sides - j - 1].y = polyp.y + ND_coord(n).y; } break; case SH_RECORD: fld = (field_t *) ND_shape_info(n); b = fld->b; obs = NEW(Ppoly_t); obs->pn = 4; obs->ps = N_NEW(4, Ppoint_t); /* CW order */ pt = ND_coord(n); if (pmargin->doAdd) { obs->ps[0] = genPt(b.LL.x-pmargin->x, b.LL.y-pmargin->y, pt); obs->ps[1] = genPt(b.LL.x-pmargin->x, b.UR.y+pmargin->y, pt); obs->ps[2] = genPt(b.UR.x+pmargin->x, b.UR.y+pmargin->y, pt); obs->ps[3] = genPt(b.UR.x+pmargin->x, b.LL.y-pmargin->y, pt); } else { obs->ps[0] = recPt(b.LL.x, b.LL.y, pt, pmargin); obs->ps[1] = recPt(b.LL.x, b.UR.y, pt, pmargin); obs->ps[2] = recPt(b.UR.x, b.UR.y, pt, pmargin); obs->ps[3] = recPt(b.UR.x, b.LL.y, pt, pmargin); } break; case SH_EPSF: desc = (epsf_t *) (ND_shape_info(n)); obs = NEW(Ppoly_t); obs->pn = 4; obs->ps = N_NEW(4, Ppoint_t); /* CW order */ pt = ND_coord(n); if (pmargin->doAdd) { obs->ps[0] = genPt(-ND_lw(n)-pmargin->x, -ND_ht(n)-pmargin->y,pt); obs->ps[1] = genPt(-ND_lw(n)-pmargin->x, ND_ht(n)+pmargin->y,pt); obs->ps[2] = genPt(ND_rw(n)+pmargin->x, ND_ht(n)+pmargin->y,pt); obs->ps[3] = genPt(ND_rw(n)+pmargin->x, -ND_ht(n)-pmargin->y,pt); } else { obs->ps[0] = recPt(-ND_lw(n), -ND_ht(n), pt, pmargin); obs->ps[1] = recPt(-ND_lw(n), ND_ht(n), pt, pmargin); obs->ps[2] = recPt(ND_rw(n), ND_ht(n), pt, pmargin); obs->ps[3] = recPt(ND_rw(n), -ND_ht(n), pt, pmargin); } break; default: obs = NULL; break; } return obs; }
static void vrml_ellipse(GVJ_t * job, pointf * A, int filled) { FILE *out = job->output_file; obj_state_t *obj = job->obj; node_t *n; edge_t *e; double z = obj->z; double rx, ry; int dx, dy; pointf npf, nqf; point np; int pen; gdImagePtr brush = NULL; rx = A[1].x - A[0].x; ry = A[1].y - A[0].y; switch (obj->type) { case ROOTGRAPH_OBJTYPE: case CLUSTER_OBJTYPE: break; case NODE_OBJTYPE: n = obj->u.n; if (shapeOf(n) == SH_POINT) { doSphere (job, n, A[0], z, rx, ry); return; } pen = set_penstyle(job, im, brush); npf = vrml_node_point(job, n, A[0]); nqf = vrml_node_point(job, n, A[1]); dx = ROUND(2 * (nqf.x - npf.x)); dy = ROUND(2 * (nqf.y - npf.y)); PF2P(npf, np); if (filled) gdImageFilledEllipse(im, np.x, np.y, dx, dy, color_index(im, obj->fillcolor)); gdImageArc(im, np.x, np.y, dx, dy, 0, 360, pen); if (brush) gdImageDestroy(brush); fprintf(out, "Transform {\n"); fprintf(out, " translation %.3f %.3f %.3f\n", A[0].x, A[0].y, z); fprintf(out, " scale %.3f %.3f 1\n", rx, ry); fprintf(out, " children [\n"); fprintf(out, " Transform {\n"); fprintf(out, " rotation 1 0 0 1.57\n"); fprintf(out, " children [\n"); fprintf(out, " Shape {\n"); fprintf(out, " geometry Cylinder { side FALSE }\n"); fprintf(out, " appearance Appearance {\n"); fprintf(out, " material Material {\n"); fprintf(out, " ambientIntensity 0.33\n"); fprintf(out, " diffuseColor 1 1 1\n"); fprintf(out, " }\n"); fprintf(out, " texture ImageTexture { url \"node%d.png\" }\n", n->id); fprintf(out, " }\n"); fprintf(out, " }\n"); fprintf(out, " ]\n"); fprintf(out, " }\n"); fprintf(out, " ]\n"); fprintf(out, "}\n"); break; case EDGE_OBJTYPE: e = obj->u.e; /* this is gruesome, but how else can we get z coord */ if (DIST2(A[0], ND_coord_i(e->tail)) < DIST2(A[0], ND_coord_i(e->head))) z = obj->tail_z; else z = obj->head_z; fprintf(out, "Transform {\n"); fprintf(out, " translation %.3f %.3f %.3f\n", A[0].x, A[0].y, z); fprintf(out, " children [\n"); fprintf(out, " Shape {\n"); fprintf(out, " geometry Sphere {radius %.3f }\n", (double) rx); fprintf(out, " appearance USE E%d\n", e->id); fprintf(out, " }\n"); fprintf(out, " ]\n"); fprintf(out, "}\n"); } }