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); }
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; }
void AddEdgeEndpointVertices(IEdge edge, Point2D? edgeStart, Point2D? edgeEnd) { if (edgeStart == null || edgeEnd == null) { // should not happen throw new System.Exception("The line between box centers does not intersect the boxes!"); } 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); }
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); }
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)); }