Пример #1
0
        /// <summary>
        /// Reconstructs the path.
        /// </summary>
        /// <param name="toPoint">To point.</param>
        /// <param name="reachedPoints">The reached points.</param>
        /// <returns>GraphPoint[].</returns>
        private static GraphPoint[] reconstructPath(GraphPoint toPoint, Dictionary <GraphPoint, GraphPoint> reachedPoints)
        {
            GraphPoint currentPoint;

            if (!reachedPoints.TryGetValue(toPoint, out currentPoint))
            {
                //path hasn't been found in current graph
                return(null);
            }

            var path = new List <GraphPoint>();

            path.Add(toPoint);

            //trace path back from reached table
            while (currentPoint != null)
            {
                path.Add(currentPoint);

                currentPoint = reachedPoints[currentPoint];
            }

            path.Reverse();
            return(path.ToArray());
        }
Пример #2
0
        /// <summary>
        /// Get contact points defined for given item
        /// <remarks>Note that because of simple getting contact points we store them as first four</remarks>.
        /// </summary>
        /// <param name="item">Item which points are generated.</param>
        /// <returns>Generated points.</returns>
        private IEnumerable <GraphPoint> generatePoints(DiagramItem item)
        {
            var span     = SceneNavigator.GetSpan(item, item.GlobalPosition);
            var topLeft  = new GraphPoint(span.TopLeft, TopLeftCorner, item);
            var topRight = new GraphPoint(span.TopRight, TopRightCorner, item);

            var bottomLeft  = new GraphPoint(span.BottomLeft, BottomLeftCorner, item);
            var bottomRight = new GraphPoint(span.BottomRight, BottomRightCorner, item);

            topLeft.SetEdgeStatus(topRight);
            topLeft.SetEdgeStatus(bottomLeft);

            bottomRight.SetEdgeStatus(topRight);
            bottomRight.SetEdgeStatus(bottomLeft);

            var points = new List <GraphPoint>();

            points.Add(topLeft);
            points.Add(topRight);
            points.Add(bottomLeft);
            points.Add(bottomRight);

            generateConnectorPoints(item.TopConnectorDrawings, ConnectorAlign.Top, item, points);
            generateConnectorPoints(item.LeftConnectorDrawings, ConnectorAlign.Left, item, points);
            generateConnectorPoints(item.BottomConnectorDrawings, ConnectorAlign.Bottom, item, points);
            generateConnectorPoints(item.RightConnectorDrawings, ConnectorAlign.Right, item, points);

            return(points);
        }
Пример #3
0
        /// <summary>
        /// Try to add edge between given points if possible.
        /// </summary>
        /// <param name="fromCandidate">Point where edge should start.</param>
        /// <param name="toCandidate">Point where edge should end.</param>
        /// <param name="target">Target that is not considered to be an obstacle.</param>
        /// <param name="obstacle">Obstacle if any is present between from and to candidate, <c>null</c> otherwise.</param>
        /// <returns><c>true</c> if edge can be added, <c>false</c> otherwise.</returns>
        private bool tryAddEdge(GraphPoint fromCandidate, GraphPoint toCandidate, DiagramItem target, out DiagramItem obstacle)
        {
            obstacle = null;
            if (
                !fromCandidate.IsInAngle(toCandidate) ||
                !toCandidate.IsInAngle(fromCandidate)
                )
            {
                //edge is not possible between given points
                return(false);
            }

            if (fromCandidate.HasEdgeStatus(toCandidate))
            {
                //edge already exists or has been forbidden earlier
                return(false);
            }

            obstacle = _navigator.GetFirstObstacle(fromCandidate.Position, toCandidate.Position);
            var isEdgeValid = obstacle == null || obstacle == target;

            fromCandidate.SetEdgeStatus(toCandidate, isEdgeValid);

            return(isEdgeValid);
        }
Пример #4
0
        /// <summary>
        /// Square part of distance from current point to given point
        /// </summary>
        /// <param name="other">Other point which distance is determined</param>
        /// <returns>Square part of distance</returns>
        internal double DistanceTo(GraphPoint other)
        {
            var oPosition = other.Position;
            var xDiff     = Position.X - oPosition.X;
            var yDiff     = Position.Y - oPosition.Y;

            return(Math.Sqrt(xDiff * xDiff + yDiff * yDiff));
        }
Пример #5
0
        /// <summary>
        /// Try to enqueue point that is candidate of from points
        /// if it hasn't already been enqueued.
        /// </summary>
        /// <param name="fromCandidate">Candidate point.</param>
        private void tryEnqueue(GraphPoint fromCandidate)
        {
            if (!_processed.Add(fromCandidate))
            {
                //point is already processed
                return;
            }

            _fromCandidates.Enqueue(fromCandidate);
        }
Пример #6
0
        /// <summary>
        /// Enqueue edge between from candidate and given obstacle.
        /// </summary>
        /// <param name="fromCandidate">Candidate from which edge is enqueued.</param>
        /// <param name="obstacle">Obstacle which will be connected.</param>
        private void enqueueWithObstacleEdges(GraphPoint fromCandidate, DiagramItem obstacle)
        {
            if (obstacle == null)
            {
                //there is no obstacle which edges can be enqueued
                return;
            }

            var contactPoints = getContactPoints(obstacle);

            foreach (var contactPoint in contactPoints)
            {
                DiagramItem contactObstacle;
                if (tryAddEdge(fromCandidate, contactPoint, obstacle, out contactObstacle))
                {
                    tryEnqueue(contactPoint);
                }
                else
                {
                    enqueueWithObstacleEdges(fromCandidate, contactObstacle);
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Gets the input slots.
        /// </summary>
        /// <param name="connectorIndex">Index of the connector.</param>
        /// <param name="connectorsCount">The connectors count.</param>
        /// <param name="connector">The connector.</param>
        /// <param name="item">The item.</param>
        /// <param name="contactPoints">The contact points.</param>
        /// <returns>GraphPoint[].</returns>
        /// <exception cref="System.NotSupportedException">Connector align  + connectorAlign</exception>
        private GraphPoint[] getInputSlots(int connectorIndex, int connectorsCount, ConnectorDrawing connector, DiagramItem item, List <GraphPoint> contactPoints)
        {
            var connectorAlign = connector.Align;

            var span = _navigator.GetSpan(item);

            //find positions of slots for inputs according to connector align
            Point slot1End, slot1Start;
            Point slot2End;

            ViewAngle slot1View;
            ViewAngle slot2View;

            GraphPoint slot1Contact;
            GraphPoint slot2Contact;

            //slots has to be parallel with same length
            switch (connectorAlign)
            {
            case ConnectorAlign.Top:
                slot1Contact = contactPoints[2];
                slot2Contact = contactPoints[3];
                slot1View    = TopLeftCorner;
                slot2View    = TopRightCorner;
                slot1End     = span.TopLeft;
                slot2End     = span.TopRight;
                slot1Start   = new Point(slot1End.X, slot1End.Y + item.TopConnectors.DesiredSize.Height);
                break;

            case ConnectorAlign.Bottom:
                slot1Contact = contactPoints[0];
                slot2Contact = contactPoints[1];
                slot1View    = BottomLeftCorner;
                slot2View    = BottomRightCorner;
                slot1End     = span.BottomLeft;
                slot2End     = span.BottomRight;
                slot1Start   = new Point(slot1End.X, slot1End.Y - item.BottomConnectors.DesiredSize.Height);
                break;

            case ConnectorAlign.Left:
                slot1Contact = contactPoints[1];
                slot2Contact = contactPoints[3];
                slot1View    = TopLeftCorner;
                slot2View    = BottomLeftCorner;
                slot1End     = span.TopLeft;
                slot2End     = span.BottomLeft;
                slot1Start   = new Point(slot1End.X + item.LeftConnectors.DesiredSize.Width, slot1End.Y);
                break;

            case ConnectorAlign.Right:
                slot1Contact = contactPoints[0];
                slot2Contact = contactPoints[2];
                slot1View    = TopRightCorner;
                slot2View    = BottomRightCorner;
                slot1End     = span.TopRight;
                slot2End     = span.BottomRight;
                slot1Start   = new Point(slot1End.X - item.RightConnectors.DesiredSize.Width, slot1End.Y);
                break;

            default:
                throw new NotSupportedException("Connector align " + connectorAlign);
            }

            var slotVector = (slot1Start - slot1End) / (connectorsCount + 2);

            var slot1 = new GraphPoint(slot1End + slotVector * connectorIndex, slot1View, item);
            var slot2 = new GraphPoint(slot2End + slotVector * (connectorsCount - connectorIndex), slot2View, item);

            slot1.SetEdgeStatus(slot1Contact);
            slot2.SetEdgeStatus(slot2Contact);

            return(new[] { slot1, slot2 });
        }
Пример #8
0
 /// <summary>
 /// Set status for edge to given point
 /// </summary>
 /// <param name="point">Point which edge status will be set</param>
 /// <param name="status">Status that will be set</param>
 internal void SetEdgeStatus(GraphPoint point, bool status = true)
 {
     _edges[point]      = status;
     point._edges[this] = status;
 }
Пример #9
0
 /// <summary>
 /// Determine that edge status for given point is already available
 /// </summary>
 /// <param name="point">Point which defines tested edge</param>
 /// <returns><c>true</c> if edge status is available, <c>false</c> otherwise</returns>
 internal bool HasEdgeStatus(GraphPoint point)
 {
     return(_edges.ContainsKey(point));
 }
Пример #10
0
 /// <summary>
 /// Determine that current point has given point in view angle
 /// </summary>
 /// <param name="point">Point which presence in view angle is tested</param>
 /// <returns><c>true</c> if point is view angle, <c>false</c> otherwise</returns>
 internal bool IsInAngle(GraphPoint point)
 {
     return(View.IsInAngle(Position, point.Position));
 }