Esempio n. 1
0
        /// <summary>
        /// Creates a closed circle of windows connected by links.
        /// </summary>
        private static AvidModelWindow[] BuildFullRing(AvidModel model, AvidRing ring, bool abovePlane)
        {
            AvidModelWindow firstWindow = null;
            AvidModelWindow previousWindow = null;

            var result = new AvidModelWindow[12];

            for (int i = 1; i <= 12; i++)
            {
                var newWindow = new AvidModelWindow((AvidDirection)i, ring, abovePlane);
                result[i - 1] = newWindow;

                if (firstWindow == null)
                {
                    firstWindow = newWindow;
                }

                if (previousWindow != null)
                {
                    model.Links.Add(new AvidModelLink(newWindow, previousWindow, 2, false, false));
                }
                previousWindow = newWindow;
                model.Windows.Add(newWindow);
            }
            //Connect first and last windows closing the circle.
            model.Links.Add(new AvidModelLink(firstWindow, previousWindow, 2, false, false));

            return result;
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a closed circle of windows connected by links.
        /// </summary>
        private static AvidModelWindow[] BuildFullRing(AvidModel model, AvidRing ring, bool abovePlane)
        {
            AvidModelWindow firstWindow    = null;
            AvidModelWindow previousWindow = null;

            var result = new AvidModelWindow[12];

            for (int i = 1; i <= 12; i++)
            {
                var newWindow = new AvidModelWindow((AvidDirection)i, ring, abovePlane);
                result[i - 1] = newWindow;

                if (firstWindow == null)
                {
                    firstWindow = newWindow;
                }

                if (previousWindow != null)
                {
                    model.Links.Add(new AvidModelLink(newWindow, previousWindow, 2, false, false));
                }
                previousWindow = newWindow;
                model.Windows.Add(newWindow);
            }
            //Connect first and last windows closing the circle.
            model.Links.Add(new AvidModelLink(firstWindow, previousWindow, 2, false, false));

            return(result);
        }
Esempio n. 3
0
 public LinkedAvidNode(AvidModelWindow window, LinkedAvidNode previousNode, AvidModelLink linkUsed)
 {
     Window = window;
     PreviousNode = previousNode;
     LinkUsed = linkUsed;
     UpdateTransitionsCount();
 }
Esempio n. 4
0
 private void ProfferNewDistance(AvidModelWindow window, int newDistance)
 {
     if (window.MinDistance == AvidModelWindow.UndefinedDistance || window.MinDistance > newDistance)
     {
         window.MinDistance = newDistance;
     }
 }
Esempio n. 5
0
 public AvidPathInfo(int distance, AvidModelWindow start, AvidModelWindow destination)
 {
     PathNodes = new List<LinkedAvidNode>();
     Distance = distance;
     Destination = destination;
     Start = start;
 }
Esempio n. 6
0
        private AvidPathInfo TracePath(LinkedAvidNode leaf, AvidModelWindow start, AvidModelWindow destination)
        {
            var pathInfo = new AvidPathInfo(leaf.NodeDistance, start, destination);

            pathInfo.PathNodes.AddRange(leaf.GetBranch());
            pathInfo.PathNodes.Reverse();
            return(pathInfo);
        }
Esempio n. 7
0
        private void InitializeNodes(AvidModel model, AvidModelWindow start, AvidModelWindow destination)
        {
            model.ClearOperationalData();
            start.MinDistance = 0;

            // We will now exclude all nodes that are on edge, except if such node is either starting point or the destination.
            foreach (var window in model.Windows.Where(window => window.IsOnSpine && !window.Equals(start) && !window.Equals(destination))) {
                window.Excluded = true;
            }
        }
Esempio n. 8
0
        private void InitializeNodes(AvidModel model, AvidModelWindow start, AvidModelWindow destination)
        {
            model.ClearOperationalData();
            start.MinDistance = 0;

            // We will now exclude all nodes that are on edge, except if such node is either starting point or the destination.
            foreach (var window in model.Windows.Where(window => window.IsOnSpine && !window.Equals(start) && !window.Equals(destination)))
            {
                window.Excluded = true;
            }
        }
Esempio n. 9
0
        private LinkedAvidNode[] BuildTree(AvidModelWindow start, AvidModelWindow destination, AvidPathingOptions options)
        {
            var rootNode = new LinkedAvidNode(start, null, null);

            var result = new List<LinkedAvidNode>();
            TraverseDescendants(result, rootNode, destination, options);

            if (result.Count > 0)
            {
                result.Sort((ndA, ndB) => ndA.NodeDistance - ndB.NodeDistance);
                int minimumDistance = result[0].NodeDistance;
                return result.Where(nd => nd.NodeDistance == minimumDistance).ToArray();
            }

            return result.ToArray();
        }
Esempio n. 10
0
        private LinkedAvidNode[] BuildTree(AvidModelWindow start, AvidModelWindow destination, AvidPathingOptions options)
        {
            var rootNode = new LinkedAvidNode(start, null, null);

            var result = new List <LinkedAvidNode>();

            TraverseDescendants(result, rootNode, destination, options);

            if (result.Count > 0)
            {
                result.Sort((ndA, ndB) => ndA.NodeDistance - ndB.NodeDistance);
                int minimumDistance = result[0].NodeDistance;
                return(result.Where(nd => nd.NodeDistance == minimumDistance).ToArray());
            }

            return(result.ToArray());
        }
Esempio n. 11
0
        public AvidPathfindingResult GetShortestPaths(AvidModel model, AvidWindow start, AvidWindow destination, AvidPathingOptions options)
        {
            AvidModelWindow startWnd       = model.ProjectWindow(start);
            AvidModelWindow destinationWnd = model.ProjectWindow(destination);

            InitializeNodes(model, startWnd, destinationWnd);

            var validLeaves = BuildTree(startWnd, destinationWnd, options);

            var result = new AvidPathfindingResult
            {
                PathExists = validLeaves.Length > 0
            };

            if (result.PathExists)
            {
                result.MinimalDistance = validLeaves[0].NodeDistance;
                result.AllShortestPaths.AddRange(validLeaves.Select(lf => TracePath(lf, startWnd, destinationWnd)));
            }
            return(result);
        }
Esempio n. 12
0
        /// <summary>
        /// Creates a green ring and attaches it to the right magenta window. Model must have magenta windows.
        /// </summary>
        private void BuildGreenRing(AvidModel model, AvidModelWindow[] adjacentFullRing, AvidModelWindow adjacentCap)
        {
            AvidModelWindow firstWindow    = null;
            AvidModelWindow previousWindow = null;

            for (int i = 0; i < 6; i++)
            {
                var newWindow = new AvidModelWindow((AvidDirection)(i * 2 + 1), AvidRing.Green, adjacentCap.AbovePlane);
                if (firstWindow == null)
                {
                    firstWindow = newWindow;
                }
                model.Links.Add(new AvidModelLink(newWindow, adjacentCap, 2, false, false));
                model.Links.Add(new AvidModelLink(newWindow, adjacentFullRing[i * 2], 2, false, false));

                int previousIndex = i == 0 ? 11 : i * 2 - 1;
                int nextIndex     = (i * 2 + 1) % 12;
                model.Links.Add(new AvidModelLink(newWindow, adjacentFullRing[previousIndex], 2, false, true));
                model.Links.Add(new AvidModelLink(newWindow, adjacentFullRing[nextIndex], 2, false, true));

                if (previousWindow != null)
                {
                    model.Links.Add(new AvidModelLink(newWindow, previousWindow, 2, false, false));
                    var cornerWindow = new AvidModelWindow((AvidDirection)(i * 2), AvidRing.Green, adjacentCap.AbovePlane);
                    model.Windows.Add(cornerWindow);
                    model.Links.Add(new AvidModelLink(cornerWindow, newWindow, 1, false, false));
                    model.Links.Add(new AvidModelLink(cornerWindow, previousWindow, 1, false, false));
                }
                previousWindow = newWindow;
                model.Windows.Add(newWindow);
            }
            //Connect first and last windows closing the circle.
            model.Links.Add(new AvidModelLink(firstWindow, previousWindow, 2, false, false));
            var closingCornerWindow = new AvidModelWindow(AvidDirection.FA, AvidRing.Green, adjacentCap.AbovePlane);

            model.Windows.Add(closingCornerWindow);
            model.Links.Add(new AvidModelLink(closingCornerWindow, firstWindow, 1, false, false));
            model.Links.Add(new AvidModelLink(closingCornerWindow, previousWindow, 1, false, false));
        }
Esempio n. 13
0
        public AvidModel BuildModel()
        {
            var result = new AvidModel();

            // Add caps.
            var upperCap = new AvidModelWindow(AvidDirection.Undefined, AvidRing.Magenta, true);
            var lowerCap = new AvidModelWindow(AvidDirection.Undefined, AvidRing.Magenta, false);
            result.Windows.Add(upperCap);
            result.Windows.Add(lowerCap);

            var emberRing = BuildFullRing(result, AvidRing.Ember, true);
            var blueUpperRing = BuildFullRing(result, AvidRing.Blue, true);
            var blueLowerRing = BuildFullRing(result, AvidRing.Blue, false);

            ConnectFullRings(result, emberRing, blueUpperRing);
            ConnectFullRings(result, emberRing, blueLowerRing);

            BuildGreenRing(result, blueUpperRing, upperCap);
            BuildGreenRing(result, blueLowerRing, lowerCap);

            return result;
        }
Esempio n. 14
0
        private void TraverseDescendants(List<LinkedAvidNode> result, LinkedAvidNode node, AvidModelWindow destination, AvidPathingOptions options)
        {
            var validTransitions = node.Window.AdjacentWindows.ToList(); // Create a new list
            validTransitions.AddRange(node.Window.DiagonalWindows);

            foreach (var transition in validTransitions)
            {
                var linkedWindow = transition.GetLinkedNode(node.Window);

                // We encountered an excluded window or we are in a loop!
                if (linkedWindow.Excluded || WindowOccuredInPath(node, linkedWindow))
                {
                    continue;
                }

                if (!CanDoTransition(node, transition, options))
                {
                    continue;
                }

                var newNode = new LinkedAvidNode(linkedWindow, node, transition);

                if (newNode.NodeDistance / 2 > MaximumDepth)
                {
                    continue;
                }

                ProfferNewDistance(linkedWindow, newNode.NodeDistance);

                if (!linkedWindow.Equals(destination))
                {
                    TraverseDescendants(result, newNode, destination, options);
                    continue;
                }

                //New node is destination and we the path is at least minDistance, but not over maxDistance.
                result.Add(newNode);
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Creates a green ring and attaches it to the right magenta window. Model must have magenta windows.
        /// </summary>
        private void BuildGreenRing(AvidModel model, AvidModelWindow[] adjacentFullRing, AvidModelWindow adjacentCap)
        {
            AvidModelWindow firstWindow = null;
            AvidModelWindow previousWindow = null;

            for (int i = 0; i < 6; i++)
            {
                var newWindow = new AvidModelWindow((AvidDirection)(i * 2 + 1), AvidRing.Green, adjacentCap.AbovePlane);
                if (firstWindow == null)
                {
                    firstWindow = newWindow;
                }
                model.Links.Add(new AvidModelLink(newWindow, adjacentCap, 2, false, false));
                model.Links.Add(new AvidModelLink(newWindow, adjacentFullRing[i * 2], 2, false, false));

                int previousIndex = i == 0 ? 11 : i * 2 - 1;
                int nextIndex = (i * 2 + 1) % 12;
                model.Links.Add(new AvidModelLink(newWindow, adjacentFullRing[previousIndex], 2, false, true));
                model.Links.Add(new AvidModelLink(newWindow, adjacentFullRing[nextIndex], 2, false, true));

                if (previousWindow != null)
                {
                    model.Links.Add(new AvidModelLink(newWindow, previousWindow, 2, false, false));
                    var cornerWindow = new AvidModelWindow((AvidDirection)(i * 2), AvidRing.Green, adjacentCap.AbovePlane);
                    model.Windows.Add(cornerWindow);
                    model.Links.Add(new AvidModelLink(cornerWindow, newWindow, 1, false, false));
                    model.Links.Add(new AvidModelLink(cornerWindow, previousWindow, 1, false, false));
                }
                previousWindow = newWindow;
                model.Windows.Add(newWindow);
            }
            //Connect first and last windows closing the circle.
            model.Links.Add(new AvidModelLink(firstWindow, previousWindow, 2, false, false));
            var closingCornerWindow = new AvidModelWindow(AvidDirection.FA, AvidRing.Green, adjacentCap.AbovePlane);
            model.Windows.Add(closingCornerWindow);
            model.Links.Add(new AvidModelLink(closingCornerWindow, firstWindow, 1, false, false));
            model.Links.Add(new AvidModelLink(closingCornerWindow, previousWindow, 1, false, false));
        }
Esempio n. 16
0
        public AvidModel BuildModel()
        {
            var result = new AvidModel();

            // Add caps.
            var upperCap = new AvidModelWindow(AvidDirection.Undefined, AvidRing.Magenta, true);
            var lowerCap = new AvidModelWindow(AvidDirection.Undefined, AvidRing.Magenta, false);

            result.Windows.Add(upperCap);
            result.Windows.Add(lowerCap);

            var emberRing     = BuildFullRing(result, AvidRing.Ember, true);
            var blueUpperRing = BuildFullRing(result, AvidRing.Blue, true);
            var blueLowerRing = BuildFullRing(result, AvidRing.Blue, false);

            ConnectFullRings(result, emberRing, blueUpperRing);
            ConnectFullRings(result, emberRing, blueLowerRing);

            BuildGreenRing(result, blueUpperRing, upperCap);
            BuildGreenRing(result, blueLowerRing, lowerCap);

            return(result);
        }
Esempio n. 17
0
        public AvidModelLink(AvidModelWindow endpointA, AvidModelWindow endpointB, int weight, bool isDiagonal, bool isPolarDiagonal)
        {
            if (endpointA == null || endpointB == null)
            {
                throw new ArgumentNullException();
            }

            if (endpointA.Equals(endpointB))
            {
                throw new ArgumentException("A window can't be connected to itself.");
            }

            if (weight < 0)
            {
                throw new ArgumentException("Link weight should be non-negative.", "weight");
            }

            EndpointA = endpointA;
            EndpointB = endpointB;
            Weight = weight;
            IsDiagonal = isDiagonal;
            IsPolarDiagonal = isPolarDiagonal;
            AddLinkToEndpoints();
        }
Esempio n. 18
0
 private AvidPathInfo TracePath(LinkedAvidNode leaf, AvidModelWindow start, AvidModelWindow destination)
 {
     var pathInfo = new AvidPathInfo(leaf.NodeDistance, start, destination);
     pathInfo.PathNodes.AddRange(leaf.GetBranch());
     pathInfo.PathNodes.Reverse();
     return pathInfo;
 }
Esempio n. 19
0
 private static bool WindowOccuredInPath(LinkedAvidNode node, AvidModelWindow window)
 {
     return node.GetBranch().Any(lan => lan.Window.Equals(window));
 }
Esempio n. 20
0
 public AvidModelWindow GetLinkedNode(AvidModelWindow currentNode)
 {
     return EndpointA.Equals(currentNode) ? EndpointB : EndpointA;
 }
Esempio n. 21
0
        private void TraverseDescendants(List <LinkedAvidNode> result, LinkedAvidNode node, AvidModelWindow destination, AvidPathingOptions options)
        {
            var validTransitions = node.Window.AdjacentWindows.ToList(); // Create a new list

            validTransitions.AddRange(node.Window.DiagonalWindows);

            foreach (var transition in validTransitions)
            {
                var linkedWindow = transition.GetLinkedNode(node.Window);

                // We encountered an excluded window or we are in a loop!
                if (linkedWindow.Excluded || WindowOccuredInPath(node, linkedWindow))
                {
                    continue;
                }

                if (!CanDoTransition(node, transition, options))
                {
                    continue;
                }

                var newNode = new LinkedAvidNode(linkedWindow, node, transition);

                if (newNode.NodeDistance / 2 > MaximumDepth)
                {
                    continue;
                }

                ProfferNewDistance(linkedWindow, newNode.NodeDistance);

                if (!linkedWindow.Equals(destination))
                {
                    TraverseDescendants(result, newNode, destination, options);
                    continue;
                }

                //New node is destination and we the path is at least minDistance, but not over maxDistance.
                result.Add(newNode);
            }
        }
Esempio n. 22
0
 /// <summary>
 /// Builds straight and diagonal links between two full rings, from amber ring either up or down.
 /// </summary>
 private static void ConnectFullRings(AvidModel model, AvidModelWindow[] ringA, AvidModelWindow[] ringB)
 {
     //We take for granted that windows with the same index in both arrays have the same direction.
     for (int i = 0; i < 12; i++)
     {
         int previousIndex = i == 0 ? 11 : i - 1;
         int nextIndex = (i + 1) % 12;
         model.Links.Add(new AvidModelLink(ringA[i], ringB[i], 2, false, false));
         model.Links.Add(new AvidModelLink(ringA[i], ringB[previousIndex], 2, true, false));
         model.Links.Add(new AvidModelLink(ringA[i], ringB[nextIndex], 2, true, false));
     }
 }
Esempio n. 23
0
 private void ProfferNewDistance(AvidModelWindow window, int newDistance)
 {
     if (window.MinDistance == AvidModelWindow.UndefinedDistance || window.MinDistance > newDistance)
     {
         window.MinDistance = newDistance;
     }
 }
Esempio n. 24
0
 private static bool WindowOccuredInPath(LinkedAvidNode node, AvidModelWindow window)
 {
     return(node.GetBranch().Any(lan => lan.Window.Equals(window)));
 }