X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fparticipant%2FRouteGraphConnectTool.java;h=7454a2f3986cfff025242c5d9557876eaa53f809;hp=f4add638742601fd3737cdee33fd44776e8a7f1b;hb=72542227673047d71c3c3f281e478c1bea82eb81;hpb=28438fa467ae60dd63515be2df724c6ff9c299c9 diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/RouteGraphConnectTool.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/RouteGraphConnectTool.java index f4add6387..7454a2f39 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/RouteGraphConnectTool.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/participant/RouteGraphConnectTool.java @@ -16,6 +16,7 @@ import java.awt.AlphaComposite; import java.awt.Composite; import java.awt.Shape; import java.awt.geom.AffineTransform; +import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.ArrayDeque; @@ -41,6 +42,7 @@ import org.simantics.diagram.connection.rendering.IRouteGraphRenderer; import org.simantics.diagram.connection.rendering.arrows.ArrowLineEndStyle; import org.simantics.diagram.connection.rendering.arrows.ILineEndStyle; import org.simantics.diagram.connection.rendering.arrows.PlainLineEndStyle; +import org.simantics.diagram.connection.segments.Segment; import org.simantics.diagram.synchronization.ISynchronizationContext; import org.simantics.diagram.synchronization.SynchronizationHints; import org.simantics.diagram.synchronization.graph.RouteGraphConnection; @@ -863,56 +865,53 @@ public class RouteGraphConnectTool extends AbstractMode { } private static RouteGraphTarget pickNearestRouteGraphConnection(ArrayList elements, double x, double y, double pd) { - // Find the nearest distance at which we get hits. - double hi = pd + 1; - double lo = hi * .01; - double limit = 0.5; - while (true) { - double delta = (hi - lo); - if (delta <= limit) - break; - - pd = (lo + hi) * .5; + Segment nearestSegment = null; + RouteLine nearestLine = null; + IElement nearestConnection = null; - boolean hit = false; - for (IElement connection : elements) { - RouteGraphNode rgn = connection.getHint(RouteGraphConnectionClass.KEY_RG_NODE); - RouteLine line = rgn.getRouteGraph().pickLine(x, y, pd); - if (line != null) { - hit = true; - break; + double minDistanceSq = Double.MAX_VALUE; + + for (IElement connection : elements) { + RouteGraphNode rgn = connection.getHint(RouteGraphConnectionClass.KEY_RG_NODE); + for (RouteLine line : rgn.getRouteGraph().getAllLines()) { + ArrayList segments = new ArrayList(); + line.collectSegments(segments); + for (Segment segment : segments) { + RoutePoint p1 = segment.p1; + RoutePoint p2 = segment.p2; + + double distanceSq = Line2D.ptSegDistSq(p1.getX(), p1.getY(), p2.getX(), p2.getY(), x, y); + if (distanceSq < minDistanceSq && distanceSq < Math.pow(pd + rgn.getSelectionStrokeWidth() / 2, 2)) { + minDistanceSq = distanceSq; + nearestSegment = segment; + nearestLine = line; + nearestConnection = connection; + } } } - - if (hit) - hi = pd; - else - lo = pd; } - // Now that the nearest hitting distance is found, find the nearest intersection. - RouteGraphTarget nearestTarget = null; - double nearest = Double.MAX_VALUE; - for (IElement connection : elements) { - RouteGraphNode rgn = connection.getHint(RouteGraphConnectionClass.KEY_RG_NODE); - RouteLine line = rgn.getRouteGraph().pickLine(x, y, pd); - if (line == null) - continue; - - Point2D intersection = intersectionPoint(x, y, line); - if (intersection == null) - continue; - - double dx = intersection.getX() - x; - double dy = intersection.getY() - y; - double dist = Math.sqrt(dx*dx + dy*dy); - if (dist < nearest) { - nearest = dist; - nearestTarget = new RouteGraphTarget(connection, rgn, line, new Point2D.Double(x, y), intersection); + if (nearestSegment != null) { + RoutePoint p1 = nearestSegment.p1; + RoutePoint p2 = nearestSegment.p2; + double d = Math.pow(p2.getX() - p1.getX(), 2.0) + Math.pow(p2.getY() - p1.getY(), 2.0); + Point2D p; + if (d == 0) { + p = new Point2D.Double(p1.getX(), p1.getY()); + } else { + double u = ((x - p1.getX()) * (p2.getX() - p1.getX()) + (y - p1.getY()) * (p2.getY() - p1.getY())) / d; + if (u > 1.0) { + p = new Point2D.Double(p2.getX(), p2.getY()); + } else if (u <= 0.0) { + p = new Point2D.Double(p1.getX(), p1.getY()); + } else { + p = new Point2D.Double(p2.getX() * u + p1.getX() * (1.0-u), (p2.getY() * u + p1.getY() * (1.0- u))); + } } + return new RouteGraphTarget(nearestConnection, nearestConnection.getHint(RouteGraphConnectionClass.KEY_RG_NODE), nearestLine, new Point2D.Double(x, y), p); + } else { + return null; } - - return nearestTarget; } static Point2D intersectionPoint(double x, double y, RouteLine line) {