private static ConnectionNodeOrientation GetOpositeOrientation(ConnectionNodeOrientation ConnectionNodeOrientation) { switch (ConnectionNodeOrientation) { case ConnectionNodeOrientation.Left: return(ConnectionNodeOrientation.Right); case ConnectionNodeOrientation.Top: return(ConnectionNodeOrientation.Bottom); case ConnectionNodeOrientation.Right: return(ConnectionNodeOrientation.Left); case ConnectionNodeOrientation.Bottom: return(ConnectionNodeOrientation.Top); default: return(ConnectionNodeOrientation.Top); } }
private static Orientation GetOrientation(ConnectionNodeOrientation sourceOrientation) { switch (sourceOrientation) { case ConnectionNodeOrientation.Left: return(Orientation.Horizontal); case ConnectionNodeOrientation.Top: return(Orientation.Vertical); case ConnectionNodeOrientation.Right: return(Orientation.Horizontal); case ConnectionNodeOrientation.Bottom: return(Orientation.Vertical); default: throw new Exception("Unknown ConnectionNodeOrientation"); } }
private static void GetNeighborCorners(ConnectionNodeOrientation orientation, Rect rect, out Point n1, out Point n2) { switch (orientation) { case ConnectionNodeOrientation.Left: n1 = rect.TopLeft; n2 = rect.BottomLeft; break; case ConnectionNodeOrientation.Top: n1 = rect.TopLeft; n2 = rect.TopRight; break; case ConnectionNodeOrientation.Right: n1 = rect.TopRight; n2 = rect.BottomRight; break; case ConnectionNodeOrientation.Bottom: n1 = rect.BottomLeft; n2 = rect.BottomRight; break; default: throw new Exception("No neighour corners found!"); } }
private static List <Point> OptimizeLinePoints(List <Point> linePoints, Rect[] rectangles, ConnectionNodeOrientation sourceOrientation, ConnectionNodeOrientation targetOrientation) { List <Point> points = new List <Point>(); int cut = 0; for (int i = 0; i < linePoints.Count; i++) { if (i >= cut) { for (int k = linePoints.Count - 1; k > i; k--) { if (IsPointVisible(linePoints[i], linePoints[k], rectangles)) { cut = k; break; } } points.Add(linePoints[i]); } } #region Line for (int j = 0; j < points.Count - 1; j++) { if (points[j].X != points[j + 1].X && points[j].Y != points[j + 1].Y) { ConnectionNodeOrientation orientationFrom; ConnectionNodeOrientation orientationTo; // orientation from point if (j == 0) { orientationFrom = sourceOrientation; } else { orientationFrom = GetOrientation(points[j], points[j - 1]); } // orientation to pint if (j == points.Count - 2) { orientationTo = targetOrientation; } else { orientationTo = GetOrientation(points[j + 1], points[j + 2]); } if ((orientationFrom == ConnectionNodeOrientation.Left || orientationFrom == ConnectionNodeOrientation.Right) && (orientationTo == ConnectionNodeOrientation.Left || orientationTo == ConnectionNodeOrientation.Right)) { double centerX = Math.Min(points[j].X, points[j + 1].X) + Math.Abs(points[j].X - points[j + 1].X) / 2; points.Insert(j + 1, new Point(centerX, points[j].Y)); points.Insert(j + 2, new Point(centerX, points[j + 2].Y)); if (points.Count - 1 > j + 3) { points.RemoveAt(j + 3); } return(points); } if ((orientationFrom == ConnectionNodeOrientation.Top || orientationFrom == ConnectionNodeOrientation.Bottom) && (orientationTo == ConnectionNodeOrientation.Top || orientationTo == ConnectionNodeOrientation.Bottom)) { double centerY = Math.Min(points[j].Y, points[j + 1].Y) + Math.Abs(points[j].Y - points[j + 1].Y) / 2; points.Insert(j + 1, new Point(points[j].X, centerY)); points.Insert(j + 2, new Point(points[j + 2].X, centerY)); if (points.Count - 1 > j + 3) { points.RemoveAt(j + 3); } return(points); } if ((orientationFrom == ConnectionNodeOrientation.Left || orientationFrom == ConnectionNodeOrientation.Right) && (orientationTo == ConnectionNodeOrientation.Top || orientationTo == ConnectionNodeOrientation.Bottom)) { points.Insert(j + 1, new Point(points[j + 1].X, points[j].Y)); return(points); } if ((orientationFrom == ConnectionNodeOrientation.Top || orientationFrom == ConnectionNodeOrientation.Bottom) && (orientationTo == ConnectionNodeOrientation.Left || orientationTo == ConnectionNodeOrientation.Right)) { points.Insert(j + 1, new Point(points[j].X, points[j + 1].Y)); return(points); } } } #endregion return(points); }
internal static List <Point> GetConnectionLine(ConnectionNodeInfo source, Point targetPoint, ConnectionNodeOrientation preferredOrientation) { List <Point> linePoints = new List <Point>(); Rect rectSource = GetRectWithMargin(source, 10); Point startPoint = GetOffsetPoint(source, rectSource); Point endPoint = targetPoint; 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 != ConnectionNodeOrientation.None) { linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource }, source.Orientation, preferredOrientation); } else { linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource }, source.Orientation, GetOpositeOrientation(source.Orientation)); } return(linePoints); }