Exemple #1
0
 public static RouteGraph InitializeVertices(IEnumerable<IRect> nodes, IEnumerable<IEdge> edges)
 {
     var graph = new RouteGraph();
     // add vertices for node corners
     foreach (var node in nodes) {
         graph.Boxes.Add(node);
         foreach (var vertex in GetRectCorners(node, boxPadding)) {
             graph.Vertices.Add(vertex);
         }
     }
     // add vertices for egde endpoints
     foreach (var multiEdgeGroup in edges.GroupBy(edge => GetStartEnd(edge))) {
         int multiEdgeCount = multiEdgeGroup.Count();
         IRect fromRect = multiEdgeGroup.First().From;
         IRect toRect = multiEdgeGroup.First().To;
         var sourceCenter = GeomUtils.RectCenter(fromRect);
         var targetCenter = GeomUtils.RectCenter(toRect);
         if (Math.Abs(sourceCenter.X - targetCenter.X) > Math.Abs(sourceCenter.Y - targetCenter.Y) ||
             (fromRect == toRect))
         {
             // the line is horizontal
             double multiEdgeSpanSource = GetMultiEdgeSpan(fromRect.Height, multiEdgeCount, multiEdgeGap);
             double multiEdgeSpanTarget = GetMultiEdgeSpan(toRect.Height, multiEdgeCount, multiEdgeGap);
             double originSourceCurrentY = sourceCenter.Y - multiEdgeSpanSource / 2;
             double originTargetCurrentY = targetCenter.Y - multiEdgeSpanTarget / 2;
             foreach (var edge in multiEdgeGroup.OrderBy(edge => edge.From == edge.To)) {
                 Point2D sourceOrigin = new Point2D(sourceCenter.X, originSourceCurrentY);
                 Point2D targetOrigin = new Point2D(targetCenter.X, originTargetCurrentY);
                 // Here user could provide custom edgeStart and edgeEnd
                 // inflate boxes a little so that edgeStart and edgeEnd are a little outside of the box (to prevent floating point errors)
                 if (edge.From == edge.To) {
                     var edgeStart = new Point2D(fromRect.Left + fromRect.Width + 0.01, originSourceCurrentY);
                     var edgeEnd = new Point2D(fromRect.Left + fromRect.Width / 2, fromRect.Top);
                     graph.AddEdgeEndpointVertices(edge, edgeStart, edgeEnd);
                 } else {
                     var edgeStart = GeomUtils.LineRectIntersection(sourceOrigin, targetOrigin, edge.From.Inflated(1e-3));
                     var edgeEnd = GeomUtils.LineRectIntersection(sourceOrigin, targetOrigin, edge.To.Inflated(1e-3));
                     graph.AddEdgeEndpointVertices(edge, edgeStart, edgeEnd);
                 }
                 originSourceCurrentY += multiEdgeSpanSource / (multiEdgeCount - 1);
                 originTargetCurrentY += multiEdgeSpanTarget / (multiEdgeCount - 1);
             }
         }
         else
         {
             // the line is vertical
             double multiEdgeSpanSource = GetMultiEdgeSpan(fromRect.Width, multiEdgeCount, multiEdgeGap);
             double multiEdgeSpanTarget = GetMultiEdgeSpan(toRect.Width, multiEdgeCount, multiEdgeGap);
             double originSourceCurrentX = sourceCenter.X - multiEdgeSpanSource / 2;
             double originTargetCurrentX = targetCenter.X - multiEdgeSpanTarget / 2;
             foreach (var edge in multiEdgeGroup.OrderBy(edge => edge.From == edge.To)) {
                 Point2D sourceOrigin = new Point2D(originSourceCurrentX, sourceCenter.Y);
                 Point2D targetOrigin = new Point2D(originTargetCurrentX, targetCenter.Y);
                 // Here user could provide custom edgeStart and edgeEnd
                 // inflate boxes a little so that edgeStart and edgeEnd are a little outside of the box (to prevent floating point errors)
                 var edgeStart = GeomUtils.LineRectIntersection(sourceOrigin, targetOrigin, edge.From.Inflated(1e-3));
                 var edgeEnd = GeomUtils.LineRectIntersection(sourceOrigin, targetOrigin, edge.To.Inflated(1e-3));
                 graph.AddEdgeEndpointVertices(edge, edgeStart, edgeEnd);
                 originSourceCurrentX += multiEdgeSpanSource / (multiEdgeCount - 1);
                 originTargetCurrentX += multiEdgeSpanTarget / (multiEdgeCount - 1);
             }
         }
     }
     return graph;
 }
Exemple #2
0
 public static Point2D Interpolate(Point2D pointA, Point2D pointB, double t)
 {
     double b = 1 - t;
     return new Point2D(pointA.X * t + pointB.X * b, pointA.Y * t + pointB.Y * b);
 }
Exemple #3
0
 void AddEdgeEndpointVertices(IEdge edge, Point2D? edgeStart, Point2D? edgeEnd)
 {
     if (edgeStart == null || edgeEnd == null) {
         // should not happen
         return;
     }
     var startPoint = new RouteVertex(edgeStart.Value.X, edgeStart.Value.Y);
     startPoint.IsEdgeEndpoint = true;
     var endPoint = new RouteVertex(edgeEnd.Value.X, edgeEnd.Value.Y);
     endPoint.IsEdgeEndpoint = true;
     this.vertices.Add(startPoint);
     this.vertices.Add(endPoint);
     // remember what RouteVertices we created for this user edge
     this.setStartVertex(edge, startPoint);
     this.setEndVertex(edge, endPoint);
 }