private static Point GetOffsetPoint(ConnectorInfo connector, Rect rect) { Point offsetPoint = new Point(); switch (connector.Orientation) { case ConnectorOrientation.Left: offsetPoint = new Point(rect.Left, connector.Position.Y); break; case ConnectorOrientation.Top: offsetPoint = new Point(connector.Position.X, rect.Top); break; case ConnectorOrientation.Right: offsetPoint = new Point(rect.Right, connector.Position.Y); break; case ConnectorOrientation.Bottom: offsetPoint = new Point(connector.Position.X, rect.Bottom); break; } return offsetPoint; }
private static void CheckPathEnd(ConnectorInfo source, ConnectorInfo sink, bool showLastLine, List<Point> linePoints) { if (showLastLine) { Point startPoint = new Point(0, 0); Point endPoint = new Point(0, 0); double marginPath = 15; switch (source.Orientation) { case ConnectorOrientation.Left: startPoint = new Point(source.Position.X - marginPath, source.Position.Y); break; case ConnectorOrientation.Top: startPoint = new Point(source.Position.X, source.Position.Y - marginPath); break; case ConnectorOrientation.Right: startPoint = new Point(source.Position.X + marginPath, source.Position.Y); break; case ConnectorOrientation.Bottom: startPoint = new Point(source.Position.X, source.Position.Y + marginPath); break; } switch (sink.Orientation) { case ConnectorOrientation.Left: endPoint = new Point(sink.Position.X - marginPath, sink.Position.Y); break; case ConnectorOrientation.Top: endPoint = new Point(sink.Position.X, sink.Position.Y - marginPath); break; case ConnectorOrientation.Right: endPoint = new Point(sink.Position.X + marginPath, sink.Position.Y); break; case ConnectorOrientation.Bottom: endPoint = new Point(sink.Position.X, sink.Position.Y + marginPath); break; } linePoints.Insert(0, startPoint); linePoints.Add(endPoint); } else { linePoints.Insert(0, source.Position); linePoints.Add(sink.Position); } }
private static Rect GetRectWithMargin(ConnectorInfo connectorThumb, double margin) { Rect rect = new Rect(connectorThumb.DesignerItemLeft, connectorThumb.DesignerItemTop, 0, 0); rect.Inflate(margin, margin); return rect; }
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[] { rectSource, rectSink }); bool flag2 = IsPointVisible(currentPoint, s2, new[] { 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 ((Distance(s1, endPoint) <= Distance(s2, endPoint))) return s1; return s2; } return s1; } if (flag2) // only s2 visible { return s2; } return new Point(double.NaN, double.NaN); }
private static Point GetNearestNeighborSource(ConnectorInfo source, Point endPoint, Rect rectSource, out bool flag) { Point n1, n2; GetNeighborCorners(source.Orientation, rectSource, out n1, out n2); if ((Distance(n1, endPoint) <= Distance(n2, endPoint))) { flag = true; return n1; } flag = false; return n2; }
public List<Point> GetConnectionLine(ConnectorInfo source, ConnectorInfo sink, bool showLastLine) { List<Point> linePoints = new List<Point>(); Rect rectSource = GetRectWithMargin(source, Margin); Rect rectSink = GetRectWithMargin(sink, Margin); Point startPoint = GetOffsetPoint(source, rectSource); Point endPoint = 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[] { rectSource, rectSink })) { linePoints.Add(endPoint); break; } Point neighbour = GetNearestVisibleNeighborSink(currentPoint, endPoint, sink, rectSource, rectSink); if (!double.IsNaN(neighbour.X)) { linePoints.Add(neighbour); linePoints.Add(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[] { 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[] { rectSource })) { if (flag) { linePoints.Add(n2); currentPoint = n2; } else { linePoints.Add(n1); currentPoint = n1; } } } } #endregion #region sink node else // Now for the sink node { Point n1, n2; Point s1, s2; GetNeighborCorners(sink.Orientation, rectSink, out s1, out s2); GetOppositeCorners(sink.Orientation, rectSink, out n1, out n2); bool n1Visible = IsPointVisible(currentPoint, n1, new[] { rectSource, rectSink }); bool n2Visible = IsPointVisible(currentPoint, n2, new[] { 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); 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); break; } if ((Distance(n1, endPoint) <= Distance(n2, endPoint))) { linePoints.Add(n1); if (rectSource.Contains(s1)) { linePoints.Add(n2); linePoints.Add(s2); } else linePoints.Add(s1); linePoints.Add(endPoint); break; } linePoints.Add(n2); if (rectSource.Contains(s2)) { linePoints.Add(n1); linePoints.Add(s1); } else linePoints.Add(s2); linePoints.Add(endPoint); break; } if (n1Visible) { linePoints.Add(n1); if (rectSource.Contains(s1)) { linePoints.Add(n2); linePoints.Add(s2); } else linePoints.Add(s1); linePoints.Add(endPoint); break; } linePoints.Add(n2); if (rectSource.Contains(s2)) { linePoints.Add(n1); linePoints.Add(s1); } else linePoints.Add(s2); linePoints.Add(endPoint); break; } #endregion } } else { linePoints.Add(endPoint); } linePoints = OptimizeLinePoints(linePoints, new[] { rectSource, rectSink }, source.Orientation, sink.Orientation); CheckPathEnd(source, sink, showLastLine, linePoints); return linePoints; }
public List<Point> GetConnectionLine(ConnectorInfo source, Point sinkPoint, ConnectorOrientation preferredOrientation) { List<Point> linePoints = new List<Point>(); Rect rectSource = GetRectWithMargin(source, 10); Point startPoint = GetOffsetPoint(source, rectSource); Point endPoint = sinkPoint; linePoints.Add(startPoint); Point currentPoint = startPoint; if (!rectSource.Contains(endPoint)) { while (true) { if (IsPointVisible(currentPoint, endPoint, new[] { rectSource })) { linePoints.Add(endPoint); break; } bool sideFlag; Point n = GetNearestNeighborSource(source, endPoint, rectSource, out sideFlag); linePoints.Add(n); currentPoint = n; if (IsPointVisible(currentPoint, endPoint, new[] { rectSource })) { linePoints.Add(endPoint); break; } Point n1, n2; GetOppositeCorners(source.Orientation, rectSource, out n1, out n2); linePoints.Add(sideFlag ? n1 : n2); linePoints.Add(endPoint); break; } } else { linePoints.Add(endPoint); } linePoints = OptimizeLinePoints(linePoints, new[] { rectSource }, source.Orientation, preferredOrientation != ConnectorOrientation.None ? preferredOrientation : GetOpositeOrientation(source.Orientation)); return linePoints; }