Ejemplo n.º 1
0
        /// <summary>
        /// Calculates routes for edges in a graph, so that they avoid nodes.
        /// </summary>
        public Dictionary <TEdge, RoutedEdge> RouteEdges <TEdge>(IEnumerable <IRect> nodes, IEnumerable <TEdge> edges)
            where TEdge : class, IEdge
        {
            var routeGraph    = RouteGraph.InitializeVertices(nodes, edges, 0, 0);
            var routedEdges   = new Dictionary <TEdge, RoutedEdge>();
            var occludedEdges = new List <TEdge>();

            foreach (var edge in edges)
            {
                var straightEdge = routeGraph.TryRouteEdgeStraight(edge);
                if (straightEdge != null)
                {
                    routedEdges[edge] = straightEdge;
                }
                else
                {
                    occludedEdges.Add(edge);
                }
            }
            if (occludedEdges.Count > 0)
            {
                // there are some edges that couldn't be routed as straight lines
                routeGraph.ComputeVisibilityGraph();
                foreach (var edge in occludedEdges)
                {
                    RoutedEdge routedEdge = routeGraph.RouteEdge(edge);
                    routedEdges[edge] = routedEdge;
                }
            }
            return(routedEdges);
        }
Ejemplo n.º 2
0
        public List <RoutedEdge> RouteEdges(IEnumerable <IRect> nodes, IEnumerable <IEdge> edges)
        {
            var routeGraph = RouteGraph.InitializeVertices(nodes, edges);
            List <RoutedEdge> routedEdges = new List <RoutedEdge>();
            var occludedEdges             = new List <IEdge>();

            foreach (IEdge edge in edges)
            {
                var straightEdge = routeGraph.TryRouteEdgeStraight(edge);
                if (straightEdge != null)
                {
                    routedEdges.Add(straightEdge);
                }
                else
                {
                    occludedEdges.Add(edge);
                }
            }
            if (occludedEdges.Count > 0)
            {
                // there are some edges that couldn't be routed as straight lines
                routeGraph.ComputeVisibilityGraph();
                foreach (IEdge edge in occludedEdges)
                {
                    RoutedEdge routedEdge = routeGraph.RouteEdge(edge);
                    routedEdges.Add(routedEdge);
                }
            }
            return(routedEdges);
        }
 public AStarShortestPathFinder(RouteGraph routeGraph)
 {
     this.graph = routeGraph;
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Initializes the RouteGraph by vertices close to corners of all nodes.
        /// </summary>
        /// <param name="boundX">X coordinates of vertices cannot be lower than this value (so that edges stay in boundaries).</param>
        /// <param name="boundY">Y coordinates of vertices cannot be lower than this value (so that edges stay in boundaries).</param>
        public static RouteGraph InitializeVertices(IEnumerable <IRect> nodes, IEnumerable <IEdge> edges, int boundX, int boundY)
        {
            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))
                {
                    if (vertex.X >= boundX && vertex.Y >= boundY)
                    {
                        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)
                    {
                        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)
                        {
                            // special case - self edge
                            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)
                    {
                        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);
        }
		public DijkstraShortestPathFinder(RouteGraph routeGraph)
		{
			this.graph = routeGraph;
		}
		public AStarShortestPathFinder(RouteGraph routeGraph)
		{
			this.graph = routeGraph;
		}
Ejemplo n.º 7
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) {
						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) {
						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;
		}
Ejemplo n.º 8
0
 public DijkstraShortestPathFinder(RouteGraph routeGraph)
 {
     this.graph = routeGraph;
 }