public static Rect GetRectWithMargin(ConnectorInfo connectorThumb, double margin) { Rect rect = new Rect(connectorThumb.DesignerItemLeft, connectorThumb.DesignerItemTop, connectorThumb.DesignerItemSize.Width, connectorThumb.DesignerItemSize.Height); rect.Inflate(margin, margin); return rect; }
/// <summary> /// 原目标,根据线条的走向获取最近的连接点-重载方法 /// </summary> /// <param name="source"></param> /// <param name="endPoint"></param> /// <param name="rectSource"></param> /// <param name="flag"></param> /// <returns></returns> public static Point GetNearestNeighborSource(ConnectorInfo source, Point endPoint, Rect rectSource, out bool flag) { Point n1, n2; // neighbors GetNeighborCorners(source.Orientation, rectSource, out n1, out n2); if ((Distance(n1, endPoint) <= Distance(n2, endPoint))) { flag = true; return n1; } else { flag = false; return n2; } }
/// <summary> /// 原目标,根据线条的走向获取最近的连接点-重载方法 /// </summary> /// <param name="source"></param> /// <param name="endPoint"></param> /// <param name="rectSource"></param> /// <param name="flag"></param> /// <returns></returns> public static Point GetNearestNeighborSource(ConnectorInfo source, Point endPoint, Rect rectSource, out bool flag) { Point n1, n2; // neighbors GetNeighborCorners(source.Orientation, rectSource, out n1, out n2); if ((Distance(n1, endPoint) <= Distance(n2, endPoint))) { flag = true; return(n1); } else { flag = false; return(n2); } }
/// <summary> /// 到达目标,根据线条的走向获取最近的连接点-重载方法 /// </summary> /// <param name="currentPoint"></param> /// <param name="endPoint"></param> /// <param name="sink"></param> /// <param name="rectSource"></param> /// <param name="rectSink"></param> /// <returns></returns> private static Point GetNearestVisibleNeighborSink(Point currentPoint, Point endPoint, ConnectorInfo sink, Rect rectSource, Rect rectSink) { Point s1, s2; 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) { if (flag2) { if (rectSink.Contains(s1)) { return(s2); } if (rectSink.Contains(s2)) { return(s1); } if ((Distance(s1, endPoint) <= Distance(s2, endPoint))) { return(s1); } else { return(s2); } } else { return(s1); } } else { if (flag2) { return(s2); } else { return(new Point(double.NaN, double.NaN)); } } }
/// <summary> /// 获取线条-重载方法 /// </summary> /// <param name="source"></param> /// <param name="sinkPoint"></param> /// <param name="preferredOrientation"></param> /// <returns></returns> internal static 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 Rect[] { 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 Rect[] { rectSource })) { linePoints.Add(endPoint); break; } else { Point n1, n2; GetOppositeCorners(source.Orientation, rectSource, out n1, out n2); if (sideFlag) { linePoints.Add(n1); } else { linePoints.Add(n2); } linePoints.Add(endPoint); break; } } } else { linePoints.Add(endPoint); } if (preferredOrientation != ConnectorOrientation.None) { linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource }, source.Orientation, preferredOrientation); } else { linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource }, source.Orientation, GetOpositeOrientation(source.Orientation)); } return(linePoints); }
/// <summary> /// 获取线条-重载方法 /// </summary> /// <param name="source"></param> /// <param name="sink"></param> /// <param name="showLastLine"></param> /// <returns></returns> internal static 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 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 { 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 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 ((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); 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); CheckPathEnd(source, sink, showLastLine, linePoints); return(linePoints); }
internal ConnectorInfo GetInfo() { ConnectorInfo info = new ConnectorInfo(); info.DesignerItemLeft = MyCanvas.GetLeft(this.ParentDesignerItem); info.DesignerItemTop = MyCanvas.GetTop(this.ParentDesignerItem); info.DesignerItemSize = new Size(this.ParentDesignerItem.ActualWidth, this.ParentDesignerItem.ActualHeight); info.Orientation = this.Orientation; info.Position = this.Position; return info; }
/// <summary> /// 获取线条-重载方法 /// </summary> /// <param name="source"></param> /// <param name="sink"></param> /// <param name="showLastLine"></param> /// <returns></returns> internal static 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 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 { 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 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 ((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); 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); CheckPathEnd(source, sink, showLastLine, linePoints); return linePoints; }
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; default: break; } return offsetPoint; }
/// <summary> /// 到达目标,根据线条的走向获取最近的连接点-重载方法 /// </summary> /// <param name="currentPoint"></param> /// <param name="endPoint"></param> /// <param name="sink"></param> /// <param name="rectSource"></param> /// <param name="rectSink"></param> /// <returns></returns> private static Point GetNearestVisibleNeighborSink(Point currentPoint, Point endPoint, ConnectorInfo sink, Rect rectSource, Rect rectSink) { Point s1, s2; 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) { if (flag2) { if (rectSink.Contains(s1)) return s2; if (rectSink.Contains(s2)) return s1; if ((Distance(s1, endPoint) <= Distance(s2, endPoint))) return s1; else return s2; } else { return s1; } } else { if (flag2) { return s2; } else { return new Point(double.NaN, double.NaN); } } }
/// <summary> /// 原目标,根据线条的走向获取最近的连接点-重载方法 /// </summary> /// <param name="source"></param> /// <param name="endPoint"></param> /// <param name="rectSource"></param> /// <param name="rectSink"></param> /// <param name="flag"></param> /// <returns></returns> private static Point GetNearestNeighborSource(ConnectorInfo source, Point endPoint, Rect rectSource, Rect rectSink, out bool flag) { Point n1, n2; 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 ((Distance(n1, endPoint) <= Distance(n2, endPoint))) { flag = true; return n1; } else { flag = false; return n2; } }
/// <summary> /// 检查线条是否结束 /// </summary> /// <param name="source"></param> /// <param name="sink"></param> /// <param name="showLastLine"></param> /// <param name="linePoints"></param> 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 - 10, source.Position.Y); break; case ConnectorOrientation.Bottom: startPoint = new Point(source.Position.X, source.Position.Y + 3); break; default: 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 + 5); break; case ConnectorOrientation.Right: endPoint = new Point(sink.Position.X + marginPath - 7, sink.Position.Y); break; case ConnectorOrientation.Bottom: endPoint = new Point(sink.Position.X, sink.Position.Y + marginPath + 3); break; default: break; } linePoints.Insert(0, startPoint); linePoints.Add(endPoint); } else { linePoints.Insert(0, source.Position); linePoints.Add(sink.Position); } }
/// <summary> /// 获取线条-重载方法 /// </summary> /// <param name="source"></param> /// <param name="sinkPoint"></param> /// <param name="preferredOrientation"></param> /// <returns></returns> internal static 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 Rect[] { 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 Rect[] { rectSource })) { linePoints.Add(endPoint); break; } else { Point n1, n2; GetOppositeCorners(source.Orientation, rectSource, out n1, out n2); if (sideFlag) linePoints.Add(n1); else linePoints.Add(n2); linePoints.Add(endPoint); break; } } } else { linePoints.Add(endPoint); } if (preferredOrientation != ConnectorOrientation.None) linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource }, source.Orientation, preferredOrientation); else linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource }, source.Orientation, GetOpositeOrientation(source.Orientation)); return linePoints; }