graph based vector graphics
http://azingoft.blogspot.de/2008/11/blog-post_10.html with this code:
Init.java: public class Init implements PluginInterface { HashSet addedGRs = new HashSet(); static final String CURVE_WIDTH = "Curve Width";
public void init(final BlackBoard blackboard) { blackboard.addListener(new Event(AbstractGraphRenderer.name), new Listener() { public void notifyRelevantActions(Event notifierName, Object value) { AbstractGraphRenderer gr = AbstractGraphRenderer.getCurrentGraphRenderer(blackboard); if (addedGRs.contains(gr)) return; gr.addPaintHandler(new Painter()); addedGRs.add(gr); } }); VertexModel.addGlobalUserDefinedAttribute(CURVE_WIDTH, 5); } }
Painter.java: public class Painter implements PaintHandler { GraphData gd = new GraphData(GraphLab.blackboard); GraphModel G = gd.getGraph();
public void paint(Graphics gr1d, Object destinationComponent) { final Graphics2D gr = (Graphics2D) gr1d; final int n = G.getVerticesCount(); if (n == 0) return;
AbstractGraphRenderer.getCurrentGraphRenderer(GraphLab.blackboard).ignoreRepaints(new Runnable() { public void run() { boolean[] marks = new boolean[n]; BaseVertex V[] = G.getVertexArray(); final VertexModel parent[] = new VertexModel[n];
//consider the hole structure as a tree
AlgorithmUtils.BFSrun(G, (VertexModel) V[0], new AlgorithmUtils.BFSListener() {
public void visit(VertexModel v, VertexModel p) {
parent[v.getId()] = p;
}
});
for (VertexModel v : G) {
if (v.getId() == 0) continue;
if (v.getColor() == 0) {
VertexModel v1 = parent[v.getId()];
if (v1 == null || v1.getColor() != 0) continue;
VertexModel v2 = parent[v1.getId()];
if (v2 == null || v2.getColor() != 0) continue;
//generate the curve between v1, v2 and v3
GraphPoint p1 = v.getLocation();
GraphPoint p2 = v1.getLocation();
GraphPoint p3 = v2.getLocation();
GraphPoint m1 = AlgorithmUtils.getMiddlePoint(p1, p2);
GraphPoint m2 = AlgorithmUtils.getMiddlePoint(p2, p3);
GraphPoint cp = p2;
Integer w1 = v.getUserDefinedAttribute(CURVE_WIDTH);
Integer w2 = v1.getUserDefinedAttribute(CURVE_WIDTH);
Integer w3 = v2.getUserDefinedAttribute(CURVE_WIDTH);
int startWidth = (w1 + w2) / 2;
int endWidth = (w3 + w2) / 2;
int middleWidth = w2;
double teta1 = AlgorithmUtils.getAngle(p1, p2);
double teta2 = AlgorithmUtils.getAngle(p1, p3);
double teta3 = AlgorithmUtils.getAngle(p2, p3);
//generate boundary curves
java.awt.geom.QuadCurve2D c1 = new QuadCurve2D.Double(
m1.x - startWidth * sin(teta1), m1.y + startWidth * cos(teta1),
cp.x - middleWidth * sin(teta2), cp.y + middleWidth * cos(teta2),
m2.x - endWidth * sin(teta3), m2.y + endWidth * cos(teta3));
java.awt.geom.QuadCurve2D c2 = new QuadCurve2D.Double(
m2.x + endWidth * sin(teta3), m2.y - endWidth * cos(teta3),
cp.x + middleWidth * sin(teta2), cp.y - middleWidth * cos(teta2),
m1.x + startWidth * sin(teta1), m1.y - startWidth * cos(teta1));
//mix them
GeneralPath gp = new GeneralPath(c1);
gp.append(c2, true);
gp.closePath();
gr.setColor(Color.black);
//fill the curve
gr.fill(gp);
}
}
}
}, false /* dont repaint after*/); } }