1 package org.simantics.sysdyn.ui.editor.routing;
\r
3 import java.awt.geom.Arc2D;
\r
4 import java.awt.geom.Path2D;
\r
5 import java.awt.geom.Point2D;
\r
6 import java.awt.geom.Rectangle2D;
\r
8 import org.simantics.g2d.routing.IConnection;
\r
9 import org.simantics.g2d.routing.IConnection.Connector;
\r
10 import org.simantics.g2d.routing.IRouter2;
\r
11 import org.simantics.sysdyn.ui.elements.connections.Arcs;
\r
12 import org.simantics.utils.datastructures.Pair;
\r
14 public class DependencyRouter implements IRouter2 {
\r
16 public static DependencyRouter INSTANCE = new DependencyRouter();
\r
19 public void route(IConnection connection) {
\r
20 if(connection.getSegments().isEmpty())
\r
22 Object seg = connection.getSegments().iterator().next();
\r
23 Connector begin = connection.getBegin(seg);
\r
24 Connector end = connection.getEnd(seg);
\r
26 Pair<Arc2D, Path2D> shapes = new Pair<Arc2D, Path2D>(new Arc2D.Double(), new Path2D.Double());
\r
27 createArrowShape(shapes,
\r
28 begin.parentObstacle,
\r
32 Path2D path = new Path2D.Double();
\r
33 path.append(shapes.first, false);
\r
34 path.append(shapes.second, false);
\r
35 connection.setPath(seg, path);
\r
40 * Total length of the arrow is ARROW_LENGTH1 + ARROW_LENGTH2
\r
42 public static double ARROW_LENGTH1 = 0.2;
\r
43 public static double ARROW_LENGTH2 = 1.0;
\r
44 public static double ARROW_WIDTH = 0.5;
\r
47 private static Path2D createArrow(Path2D shape, double x, double y, double dx, double dy) {
\r
49 shape = new Path2D.Double();
\r
53 shape.moveTo(x+ARROW_LENGTH1*dx, y+ARROW_LENGTH1*dy);
\r
54 x -= ARROW_LENGTH2*dx;
\r
55 y -= ARROW_LENGTH2*dy;
\r
56 shape.lineTo(x-ARROW_WIDTH*dy, y+ARROW_WIDTH*dx);
\r
57 shape.lineTo(x+ARROW_WIDTH*dy, y-ARROW_WIDTH*dx);
\r
62 public static Arc2D createArc(Arc2D arc, Rectangle2D tail, Rectangle2D head, double angle) {
\r
63 double x0 = tail.getCenterX();
\r
64 double y0 = tail.getCenterY();
\r
65 double x1 = head.getCenterX();
\r
66 double y1 = head.getCenterY();
\r
68 // System.out.println("createArrowShape " + x0 + " " + y0 + " " + x1 + " " + y1);
\r
71 Math.abs(angle) < 1.0e-6
\r
72 ? 1e3 * Math.signum(angle)
\r
73 : Math.tan(Math.PI*0.5-angle)*0.5;
\r
75 double cx = 0.5*(x0+x1) + offset * (y1-y0);
\r
76 double cy = 0.5*(y0+y1) + offset * (x0-x1);
\r
77 double dx0 = x0 - cx;
\r
78 double dy0 = y0 - cy;
\r
79 double dx1 = x1 - cx;
\r
80 double dy1 = y1 - cy;
\r
82 double r = Math.sqrt(dx0*dx0 + dy0*dy0);
\r
84 // Rectangle2D bounds = new Rectangle2D.Double();
\r
85 // tail.getBounds(bounds);
\r
86 double angle0 = Arcs.nextIntersectingAngle(cx, cy, r,
\r
87 Math.atan2(-dy0, dx0), tail, angle < 0.0);
\r
88 // head.getBounds(bounds);
\r
89 double angle1 = Arcs.nextIntersectingAngle(cx, cy, r,
\r
90 Math.atan2(-dy1, dx1), head, angle > 0.0);
\r
91 double extent = angle1-angle0;
\r
92 //double arcAngle = angle0;
\r
94 double temp = angle0;
\r
100 extent += Math.PI*2.0;
\r
101 else if(extent >= 360.0)
\r
102 extent -= Math.PI*2.0;
\r
104 arc = new Arc2D.Double();
\r
105 arc.setArc(cx-r, cy-r, 2*r, 2*r,
\r
106 Math.toDegrees(angle0),
\r
107 Math.toDegrees(extent),
\r
113 public static Point2D computeCenter(Rectangle2D tail, Rectangle2D head, double angle) {
\r
115 double x0 = tail.getCenterX();
\r
116 double y0 = tail.getCenterY();
\r
117 double x1 = head.getCenterX();
\r
118 double y1 = head.getCenterY();
\r
120 // System.out.println("createArrowShape " + x0 + " " + y0 + " " + x1 + " " + y1);
\r
123 Math.abs(angle) < 1.0e-6
\r
124 ? 1e3 * Math.signum(angle)
\r
125 : Math.tan(Math.PI*0.5-angle)*0.5;
\r
127 double cx = 0.5*(x0+x1) + offset * (y1-y0);
\r
128 double cy = 0.5*(y0+y1) + offset * (x0-x1);
\r
130 return new Point2D.Double(cx, cy);
\r
134 public static Pair<Arc2D, Path2D> createArrowShape(Pair<Arc2D, Path2D> shapes, Rectangle2D tail, Rectangle2D head, double angle) {
\r
135 if(shapes == null || shapes.first == null || shapes.second == null) {
\r
136 shapes = new Pair<Arc2D, Path2D>(new Arc2D.Double(), new Path2D.Double());
\r
139 createArc(shapes.first, tail, head, angle);
\r
141 double angle0 = Math.toRadians(shapes.first.getAngleStart());
\r
142 double angle1 = Math.toRadians(shapes.first.getAngleStart() + shapes.first.getAngleExtent());
\r
143 double x = Math.cos(angle > 0.0 ? angle1 : angle0);
\r
144 double y = -Math.sin(angle > 0.0 ? angle1 : angle0);
\r
145 double r = shapes.first.getHeight() / 2;
\r
147 createArrow(shapes.second, shapes.first.getCenterX() + r*x, shapes.first.getCenterY() + r*y,
\r
148 angle < 0.0 ? -y : y,
\r
149 angle > 0.0 ? -x : x);
\r