package org.simantics.debug.graphical.model; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Line2D; import java.awt.geom.Path2D; import java.awt.geom.Point2D; public class Edge { private static final double ARROW_LENGTH = 10.0; private static final double ARROW_MIDDLE_LENGTH = 8.0; private static final double ARROW_RADIUS = 4.0; Node a; Node b; Content content; public Edge(Node a, Node b) { this.a = a; this.b = b; } public Node getA() { return a; } public Node getB() { return b; } public void setContent(Content content) { this.content = content; } public void render(Graphics2D g) { Point2D pa = a.clipLineFromCenter(b.x, b.y); Point2D pb = b.clipLineFromCenter(a.x, a.y); double dx, dy; double l; drawArrow: { Path2D path = new Path2D.Double(); double x = pb.getX(); double y = pb.getY(); dx = pa.getX() - x; dy = pa.getY() - y; l = Math.sqrt(dx*dx + dy*dy); if(l < 0.1) break drawArrow; dx /= l; dy /= l; path.moveTo(x, y); path.lineTo(x+ARROW_LENGTH*dx+ARROW_RADIUS*dy, y+ARROW_LENGTH*dy-ARROW_RADIUS*dx); path.lineTo(x+ARROW_MIDDLE_LENGTH*dx, y+ARROW_MIDDLE_LENGTH*dy); path.lineTo(x+ARROW_LENGTH*dx-ARROW_RADIUS*dy, y+ARROW_LENGTH*dy+ARROW_RADIUS*dx); path.closePath(); g.fill(path); pb.setLocation(pb.getX()+dx*ARROW_MIDDLE_LENGTH, pb.getY()+dy*ARROW_MIDDLE_LENGTH); } g.draw(new Line2D.Double(pa, pb)); if(content != null) { if(l < content.radiusX*2.1) { /*double ss = - Math.abs(dy)*content.radiusX + Math.abs(dx)*content.radiusY + 3.0; double tx = 0.5*(pa.getX() + pb.getX()) - dy*ss; double ty = 0.5*(pa.getY() + pb.getY()) + dx*ss; */ double tx = 0.5*(pa.getX() + pb.getX()) + Math.signum(dy) * content.radiusX; double ty = 0.5*(pa.getY() + pb.getY()) - Math.signum(dx) * content.radiusY; content.render(g, tx, ty); } else { double ss = content.radiusY*0.5+1.0; double tx = 0.5*(pa.getX() + pb.getX()) - dy*ss; double ty = 0.5*(pa.getY() + pb.getY()) + dx*ss; content.render(g, new AffineTransform(-dx, -dy, dy, -dx, tx, ty)); } } } }