/// <summary> /// Fix the ports for <see cref="RoutingMode.ShortestStraightPathToBorder"/> /// by enlarging the adjacent segment to the rotated layout. /// </summary> /// <param name="graph">The layout graph to work on.</param> /// <param name="edge">The edge to fix.</param> /// <param name="path">A <see cref="GeneralPath"/> which represents the rotated layout.</param> /// <param name="atSource">Whether to fix the source or target port of the edge.</param> private static void FixPorts(LayoutGraph graph, Edge edge, GeneralPath path, bool atSource) { var el = graph.GetLayout(edge); var pointCount = el.PointCount(); // find the opposite point of the port at the adjacent segment PointD firstBend = atSource ? (pointCount > 0 ? el.GetPoint(0) : graph.GetTargetPointAbs(edge)).ToPointD() : (pointCount > 0 ? el.GetPoint(pointCount - 1) : graph.GetSourcePointAbs(edge)).ToPointD(); // The port itself PointD port = (atSource ? graph.GetSourcePointAbs(edge) : graph.GetTargetPointAbs(edge)).ToPointD(); // The adjacent segment as vector pointing from the opposite point to the port var direction = port - firstBend; // find the intersection (there is always one) var intersection = path.FindRayIntersection(firstBend.ToPointD(), direction); PointD point = port; if (intersection < Double.PositiveInfinity) { // found an intersection: extend the adjacent segment point = firstBend + (direction * intersection); } else { // no intersection: connect to the original port's nearest point var cursor = path.CreateCursor(); double minDistance = Double.PositiveInfinity; while (cursor.MoveNext()) { var distance = port.DistanceTo(cursor.CurrentEndPoint); if (distance < minDistance) { minDistance = distance; point = cursor.CurrentEndPoint; } } } // set the port position if (atSource) { graph.SetSourcePointAbs(edge, point.ToYPoint()); } else { graph.SetTargetPointAbs(edge, point.ToYPoint()); } }