private static Point GetNearestNeighborSource(ConnectorInfo source, Point endPoint, Rect rectSource, Rect rectSink, out bool flag) { Point n1, n2; // neighbors GetNeighborCorners(source.Orientation, rectSource, out n1, out n2); if (rectSink.Contains(n1)) { flag = false; return(n2); } if (rectSink.Contains(n2)) { flag = true; return(n1); } if ((PathFinderHelper.Distance(n1, endPoint) <= PathFinderHelper.Distance(n2, endPoint))) { flag = true; return(n1); } else { flag = false; return(n2); } }
private static Point GetNearestVisibleNeighborSink(Point currentPoint, Point endPoint, ConnectorInfo sink, Rect rectSource, Rect rectSink) { Point s1, s2; // neighbors on sink side GetNeighborCorners(sink.Orientation, rectSink, out s1, out s2); bool flag1 = IsPointVisible(currentPoint, s1, new Rect[] { rectSource, rectSink }); bool flag2 = IsPointVisible(currentPoint, s2, new Rect[] { rectSource, rectSink }); if (flag1) // s1 visible { if (flag2) // s1 and s2 visible { if (rectSink.Contains(s1)) { return(s2); } if (rectSink.Contains(s2)) { return(s1); } if ((PathFinderHelper.Distance(s1, endPoint) <= PathFinderHelper.Distance(s2, endPoint))) { return(s1); } else { return(s2); } } else { return(s1); } } else // s1 not visible { if (flag2) // only s2 visible { return(s2); } else // s1 and s2 not visible { return(new Point(double.NaN, double.NaN)); } } }
public override List <Point> GetConnectionLine(ConnectorInfo source, ConnectorInfo sink, bool showLastLine) { List <Point> linePoints = new List <Point>(); Rect rectSource = PathFinderHelper.GetRectWithMargin(source, margin); Rect rectSink = PathFinderHelper.GetRectWithMargin(sink, margin); Point startPoint = PathFinderHelper.GetOffsetPoint(source, rectSource); Point endPoint = PathFinderHelper.GetOffsetPoint(sink, rectSink); linePoints.Add(startPoint); Point currentPoint = startPoint; if (!rectSink.Contains(currentPoint) && !rectSource.Contains(endPoint)) { while (true) { #region source node if (IsPointVisible(currentPoint, endPoint, new Rect[] { rectSource, rectSink })) { linePoints.Add(endPoint); currentPoint = endPoint; break; } Point neighbour = GetNearestVisibleNeighborSink(currentPoint, endPoint, sink, rectSource, rectSink); if (!double.IsNaN(neighbour.X)) { linePoints.Add(neighbour); linePoints.Add(endPoint); currentPoint = endPoint; break; } if (currentPoint == startPoint) { bool flag; Point n = GetNearestNeighborSource(source, endPoint, rectSource, rectSink, out flag); linePoints.Add(n); currentPoint = n; if (!IsRectVisible(currentPoint, rectSink, new Rect[] { rectSource })) { Point n1, n2; GetOppositeCorners(source.Orientation, rectSource, out n1, out n2); if (flag) { linePoints.Add(n1); currentPoint = n1; } else { linePoints.Add(n2); currentPoint = n2; } if (!IsRectVisible(currentPoint, rectSink, new Rect[] { rectSource })) { if (flag) { linePoints.Add(n2); currentPoint = n2; } else { linePoints.Add(n1); currentPoint = n1; } } } } #endregion #region sink node else // from here on we jump to the sink node { Point n1, n2; // neighbour corner Point s1, s2; // opposite corner GetNeighborCorners(sink.Orientation, rectSink, out s1, out s2); GetOppositeCorners(sink.Orientation, rectSink, out n1, out n2); bool n1Visible = IsPointVisible(currentPoint, n1, new Rect[] { rectSource, rectSink }); bool n2Visible = IsPointVisible(currentPoint, n2, new Rect[] { rectSource, rectSink }); if (n1Visible && n2Visible) { if (rectSource.Contains(n1)) { linePoints.Add(n2); if (rectSource.Contains(s2)) { linePoints.Add(n1); linePoints.Add(s1); } else { linePoints.Add(s2); } linePoints.Add(endPoint); currentPoint = endPoint; break; } if (rectSource.Contains(n2)) { linePoints.Add(n1); if (rectSource.Contains(s1)) { linePoints.Add(n2); linePoints.Add(s2); } else { linePoints.Add(s1); } linePoints.Add(endPoint); currentPoint = endPoint; break; } if ((PathFinderHelper.Distance(n1, endPoint) <= PathFinderHelper.Distance(n2, endPoint))) { linePoints.Add(n1); if (rectSource.Contains(s1)) { linePoints.Add(n2); linePoints.Add(s2); } else { linePoints.Add(s1); } linePoints.Add(endPoint); currentPoint = endPoint; break; } else { linePoints.Add(n2); if (rectSource.Contains(s2)) { linePoints.Add(n1); linePoints.Add(s1); } else { linePoints.Add(s2); } linePoints.Add(endPoint); currentPoint = endPoint; break; } } else if (n1Visible) { linePoints.Add(n1); if (rectSource.Contains(s1)) { linePoints.Add(n2); linePoints.Add(s2); } else { linePoints.Add(s1); } linePoints.Add(endPoint); currentPoint = endPoint; break; } else { linePoints.Add(n2); if (rectSource.Contains(s2)) { linePoints.Add(n1); linePoints.Add(s1); } else { linePoints.Add(s2); } linePoints.Add(endPoint); currentPoint = endPoint; break; } } #endregion } } else { linePoints.Add(endPoint); } linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource, rectSink }, source.Orientation, sink.Orientation); linePoints.Insert(0, new Point(source.Position.X, source.Position.Y)); linePoints.Add(new Point(sink.Position.X, sink.Position.Y)); return(linePoints); }