override protected void CollectGridSnapResults(GraphSnapContext context, CollectSnapResultsEventArgs args, RectD suggestedLayout, INode node) { // node.Layout isn't updated, yet, so we have to calculate the delta between the the new suggested layout and the current node.Layout PointD delta = suggestedLayout.TopLeft - node.Layout.GetTopLeft(); // get outline of the shape and iterate over it's path point IShapeGeometry geometry = node.Style.Renderer.GetShapeGeometry(node, node.Style); GeneralPath outline = geometry.GetOutline(); if (outline != null) { GeneralPath.PathCursor cursor = outline.CreateCursor(); while (cursor.MoveNext()) { // ignore PathType.Close as we had the path point as first point // and cursor.CurrentEndPoint is always (0, 0) for PathType.Close if (cursor.PathType != PathType.Close) { // adjust path point by the delta calculated above and add an according SnapResult PointD endPoint = cursor.CurrentEndPoint + delta; AddGridSnapResultCore(context, args, endPoint, node, GridSnapTypes.GridPoints, SnapPolicy.ToNearest, SnapPolicy.ToNearest); } } } }
/// <summary> /// Creates the geometry for the path from the given GeneralPath. /// </summary> private Geometry CreateGeometry(GeneralPath gp) { PolyLineSegment pl = new PolyLineSegment(); PathFigure figure = new PathFigure { Segments = { pl } }; // create path if (gp != null) { var cursor = gp.CreateCursor(); if (cursor.MoveNext()) { figure.StartPoint = cursor.CurrentEndPoint; } // loop all bends of the edge while (cursor.MoveNext()) { pl.Points.Add(cursor.CurrentEndPoint); } } return(new PathGeometry { Figures = { figure } }); }
/// <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()); } }