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 }
            });
        }
Beispiel #3
0
        /// <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());
            }
        }