]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/RouteGraph.java
Support for random shaped terminals
[simantics/platform.git] / bundles / org.simantics.diagram.connection / src / org / simantics / diagram / connection / RouteGraph.java
index 62d3de68fae5f110a6b08eb80dcc7558ca34df80..9b707eae7e51524ec96c298042d9694e369cd4e5 100644 (file)
  *******************************************************************************/
 package org.simantics.diagram.connection;
 
-import gnu.trove.list.array.TDoubleArrayList;
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.awt.geom.Line2D;
 import java.awt.geom.Path2D;
+import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.io.PrintStream;
 import java.io.Serializable;
@@ -34,6 +30,11 @@ import org.simantics.diagram.connection.rendering.arrows.PlainLineEndStyle;
 import org.simantics.diagram.connection.segments.Segment;
 import org.simantics.diagram.connection.splitting.SplittedRouteGraph;
 
+import gnu.trove.list.array.TDoubleArrayList;
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+
 public class RouteGraph implements Serializable {
 
     private static final long serialVersionUID = 2004022454972623908L;
@@ -41,12 +42,12 @@ public class RouteGraph implements Serializable {
     public static final boolean RETURN_UNMODIFIABLE_COLLECTIONS = false;
     public static final boolean CHECK_PARAMERS = true;
 
-    ArrayList<RouteLine> lines = new ArrayList<RouteLine>(4);
-    ArrayList<RouteTerminal> terminals = new ArrayList<RouteTerminal>(4);
-    ArrayList<RouteLine> transientLines = new ArrayList<RouteLine>(4);
-    int caseId;
-    boolean isSimpleConnection;
-    boolean needsUpdate = false;
+    protected ArrayList<RouteLine> lines = new ArrayList<RouteLine>(4);
+    protected ArrayList<RouteTerminal> terminals = new ArrayList<RouteTerminal>(4);
+    protected ArrayList<RouteLine> transientLines = new ArrayList<RouteLine>(4);
+    protected int caseId;
+    protected boolean isSimpleConnection;
+    protected boolean needsUpdate = false;
 
     public void updateTerminals() {
         boolean changed = false;
@@ -269,7 +270,7 @@ public class RouteGraph implements Serializable {
         needsUpdate = true;
     }
     
-    void removeTransientRouteLines() {
+    protected void removeTransientRouteLines() {
         for(RouteLine line : transientLines)
             line.remove();
         transientLines.clear();
@@ -335,6 +336,11 @@ public class RouteGraph implements Serializable {
                 line.addPoint(b);
                 line.terminal = a;
                 transientLines.add(line);
+                
+                // Path terminal
+                a.line = line;
+                b.line = line;
+                
                 break;
             }
             case SimpleConnectionUtility.ONE_BEND_HORIZONTAL_VERTICAL: {
@@ -347,6 +353,10 @@ public class RouteGraph implements Serializable {
                 line2.terminal = b;
                 transientLines.add(line1);
                 transientLines.add(line2);
+               
+                // Path terminal
+                a.line = line1;
+                b.line = line2;
                 break;
             }
             case SimpleConnectionUtility.ONE_BEND_VERTICAL_HORIZONTAL: {
@@ -359,6 +369,10 @@ public class RouteGraph implements Serializable {
                 line2.terminal = b;
                 transientLines.add(line1);
                 transientLines.add(line2);
+                
+                //Path terminal
+                a.line = line1;
+                b.line = line2;
                 break;
             }
             case SimpleConnectionUtility.MORE_BENDS_BBS_DONT_INTERSECT: 
@@ -374,6 +388,7 @@ public class RouteGraph implements Serializable {
                 break;
             }
             }
+            //routeFromTerminals(caseId==SimpleConnectionUtility.MORE_BENDS_BBS_INTERSECT);
         }
         else {
             caseId = SimpleConnectionUtility.COMPLEX_CONNECTION;
@@ -395,7 +410,7 @@ public class RouteGraph implements Serializable {
         }
     }
     
-    static class Interval {
+    public static class Interval {
         public final double min;
         public final double max;
         public Interval(double min, double max) {
@@ -404,7 +419,7 @@ public class RouteGraph implements Serializable {
         }
     }
     
-    class IntervalCache {
+    public class IntervalCache {
         THashMap<RouteLine, Interval> cache = 
                 new THashMap<RouteLine, Interval>();
         public Interval get(RouteLine line) {
@@ -456,7 +471,7 @@ public class RouteGraph implements Serializable {
         }
     } 
     
-    private void routeFromTerminals(boolean boundingBoxesIntersect) {
+    protected void routeFromTerminals(boolean boundingBoxesIntersect) {
         IntervalCache cache = new IntervalCache();
         for(RouteTerminal terminal : terminals) 
             if(terminal.line != null) {
@@ -1474,6 +1489,46 @@ public class RouteGraph implements Serializable {
             routeLine.collectSegments(segments);
         return segments;
     }
+    
+    public Segment findNearestSegment(double x, double y) {
+        Segment nearest = null;
+        double minDistanceSq = Double.MAX_VALUE;
+
+        for (Segment segment : getSegments()) {
+            RoutePoint p1 = segment.p1;
+            RoutePoint p2 = segment.p2;
+
+            double distanceSq = Line2D.ptSegDistSq(p1.x, p1.y, p2.x, p2.y, x, y);
+            if (distanceSq < minDistanceSq) {
+                minDistanceSq = distanceSq;
+                nearest = segment;
+            }
+        }
+        return nearest;
+    }
+
+    public Point2D findNearestPoint(double x, double y) {
+        Segment nearest = findNearestSegment(x, y);
+        if (nearest == null) return null;
+
+        RoutePoint p1 = nearest.p1;
+        RoutePoint p2 = nearest.p2;
+
+        double d = Math.pow(p2.x - p1.x, 2.0) + Math.pow(p2.y - p1.y, 2.0);
+
+        if (d == 0) {
+            return new Point2D.Double(p1.x, p1.y);
+        } else {
+            double u = ((x - p1.x) * (p2.x - p1.x) + (y - p1.y) * (p2.y - p1.y)) / d;
+            if (u > 1.0) {
+                return new Point2D.Double(p2.x, p2.y);
+            } else if (u <= 0.0) {
+                return new Point2D.Double(p1.x, p1.y);
+            } else {
+                return new Point2D.Double(p2.x * u + p1.x * (1.0-u), (p2.y * u + p1.y * (1.0- u)));
+            }
+        }
+    }
 
     public Path2D getPath2D() {
         Path2D result = new Path2D.Double();