X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fparticipant%2FRouteGraphConnectTool.java;h=7454a2f3986cfff025242c5d9557876eaa53f809;hb=a96e5125d72579c43abd70eb5c23de835324eaad;hp=e39c73d809120b760110c3476d44368f76e78336;hpb=05690e88acf9883a20f1480d4636c5cd037b49ea;p=simantics%2Fplatform.git 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 e39c73d80..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; @@ -33,7 +34,6 @@ import org.simantics.db.WriteGraph; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.diagram.connection.RouteGraph; -import org.simantics.diagram.connection.RouteGraphConnectionClass; import org.simantics.diagram.connection.RouteLine; import org.simantics.diagram.connection.RoutePoint; import org.simantics.diagram.connection.RouteTerminal; @@ -42,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; @@ -77,6 +78,7 @@ import org.simantics.g2d.element.handler.impl.BranchPointTerminal; import org.simantics.g2d.element.impl.Element; import org.simantics.g2d.elementclass.FlagClass; import org.simantics.g2d.elementclass.FlagHandler; +import org.simantics.g2d.elementclass.RouteGraphConnectionClass; import org.simantics.g2d.participant.TransformUtil; import org.simantics.g2d.utils.geom.DirectionSet; import org.simantics.scenegraph.g2d.G2DParentNode; @@ -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) {