예제 #1
0
        private List <Point2D> RouteSpline(List <Point2D> anchorPoints)
        {
            var result = new List <Point2D>();

            if (anchorPoints.Count == 0)
            {
                return(new List <Point2D>());
            }
            Point2D point1 = anchorPoints[0];

            result.Add(point1);
            for (int i = 2; i < anchorPoints.Count; i++)
            {
                var point2  = anchorPoints[i - 1];
                var point3  = anchorPoints[i];
                var anchor1 = GeomUtils.Interpolate(point1, point2, 1 - tBend);
                var anchor2 = GeomUtils.Interpolate(point2, point3, tBend);
                // straight segment
                result.Add(anchor1);                    // guide point1 ->  anchor1
                result.Add(point1);
                result.Add(anchor1);                    // guide anchor1 -> point2
                // bend
                result.Add(point2);                     // guide anchor1 ->  point2 (more carved ?)
                result.Add(point2);
                result.Add(anchor2);                    // guide point2 ->  anchor2
                point1 = anchor2;
            }
            // last straight segment
            var lastPoint = anchorPoints[anchorPoints.Count - 1];

            result.Add(lastPoint);
            result.Add(point1);
            result.Add(lastPoint);
            return(result);
        }
예제 #2
0
 public IRect Inflated(double padding)
 {
     //if (inflatedCache.ContainsKey(padding))
     if (inflatedCache == null)
     {
         inflatedCache = GeomUtils.InflateRect(this, padding);
     }
     return(inflatedCache);
 }
예제 #3
0
 public bool Visible(IPoint vertex, IPoint vertex2)
 {
     // test for intersection with every box
     foreach (var rect in this.Boxes)
     {
         if (GeomUtils.LineRectIntersection(vertex, vertex2, rect) != null)
         {
             return(false);
         }
     }
     return(true);
 }
예제 #4
0
 public RouteGraphEdge(RouteVertex startVertex, RouteVertex endVertex)
 {
     this.StartVertex = startVertex;
     this.EndVertex   = endVertex;
     this.Length      = GeomUtils.LineLenght(startVertex, endVertex);
 }
예제 #5
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);
        }