/// <summary>
        /// This method continuously creates nodes when certain conditions are met and also removes parrallel lines along the way.
        /// </summary>
        private void CreateNodes(Node node, int xDirection, int yDirection)
        {
            bool HitWall  = false,
                 Done     = false,
                 DontSave = false,
                 Found    = false,
                 InNodes  = false;

            int AmountOfNodes = 1,
                XPos          = node.XCoordinate,
                YPos          = node.YCoordinate;
            CreateNodesStackElement Iteration;

            List <Node> Temp = new List <Node>(); // Storage for nodes, before it's known if they have to be saved
            Stack <CreateNodesStackElement> IterationStorage = new Stack <CreateNodesStackElement>();

            IterationStorage.Push(new CreateNodesStackElement(node, xDirection, yDirection));
            while (IterationStorage.Count > 0)
            {
                HitWall       = false;
                Done          = false;
                DontSave      = false;
                Found         = false;
                InNodes       = false;
                AmountOfNodes = 1;
                Iteration     = IterationStorage.Pop();
                node          = Iteration.Node;
                xDirection    = Iteration.XDirection;
                yDirection    = Iteration.YDirection;
                Temp.Clear();
                Temp.Add(node);
                XPos = node.XCoordinate;
                YPos = node.YCoordinate;
                // Prevents a parallel line from being created
                if (ParallelLineCheck(Temp.ElementAt(0), xDirection, yDirection))
                {
                    Done     = true;
                    DontSave = true;
                }
                while (!HitWall && !Done)
                {
                    //Console.WriteLine("[DEBUG] Im at: [" + XPos + ", " + YPos + "]"); DEBUG PRINT
                    XPos = XPos + xDirection;
                    YPos = YPos + yDirection;
                    // Prevents outofindex error
                    if (OutofBounds(XPos, xDirection, YPos, yDirection))
                    {
                        Done     = true;
                        DontSave = true;
                    }
                    // Stops the creation of nodes, if it hits a wall while still inside a door
                    else if (Img.GetPixel(XPos, YPos) == Standards.Wall && Standards.IsDoorColor(Img.GetPixel(XPos - xDirection, YPos - yDirection)))
                    {
                        Done     = true;
                        DontSave = true;
                    }
                    else if (Img.GetPixel(XPos, YPos) == Standards.Wall)
                    {
                        // Prevents the creating of new nodes, if the funtion was started to close to a wall
                        if (MinPixelSizeDoor > AmountOfNodes)
                        {
                            Done = true;
                        }
                        else
                        {
                            HitWall = true;
                        }
                    }
                    //Checks if the next tile is a door or staircase
                    else if (Standards.IsDoorColor(Img.GetPixel(XPos + xDirection, YPos + yDirection)) || Img.GetPixel(XPos + xDirection, YPos + yDirection) == Standards.StairColor)
                    {
                        // If nodes are hitting a new door, it creates a new node and connects to the node in the door
                        if (!Standards.IsDoorColor(Img.GetPixel(XPos, YPos)) && Img.GetPixel(XPos, YPos) != Standards.StairColor)
                        {
                            CreateNewConnectionNode(Temp, XPos, YPos);
                            AmountOfNodes++;
                            Done = true;
                            ConnectNodes(Temp.Last(), FindClosestDoorNode(XPos, YPos));
                        }
                    }
                    else if (Standards.IsDoorColor(Img.GetPixel(XPos, YPos)) || Img.GetPixel(XPos, YPos) == Standards.StairColor)
                    {       // Prevents parallellines from being created, when leaving a door with a width of more than 1 pixel
                        if (ParallelLineCheck(new Node(XPos + xDirection, YPos + yDirection), xDirection, yDirection))
                        {
                            Done     = true;
                            DontSave = true;
                        }
                    }
                    // If it hits a another node, it will create a new node and connect to it
                    else if (Img.GetPixel(XPos + xDirection, YPos + yDirection) == Standards.NodeColor)
                    {
                        CreateNewConnectionNode(Temp, XPos, YPos);
                        AmountOfNodes++;
                        //Tries to find the node, it hits in the nodes list, gets null if node not found
                        Node target = GetNodeFromList(Nodes, XPos + xDirection, YPos + yDirection);
                        if (target != null)
                        {
                            ConnectNodes(Temp.Last(), target);
                            Found = true;
                        }
                        if (!Found)
                        {
                            target = GetNodeFromList(ConnectionNodes, XPos + xDirection, YPos + yDirection);
                            ConnectNodes(Temp.Last(), target);
                            Nodes.Add(target);
                            ConnectionNodes.Remove(target);
                        }
                        Done = true;
                    }
                    // Creates a new node and continues
                    else if (Img.GetPixel(XPos, YPos) != Standards.Wall)
                    {
                        CreateNewConnectionNode(Temp, XPos, YPos);
                        AmountOfNodes++;
                    }
                }
                // Moves the nodes over in connectionNodes, if the nodes has to be saved and colors the nodes on the image
                if (!DontSave)
                {
                    ConnectionNodes.AddRange(Temp);
                    for (int i = 1; i < Temp.Count; i++)
                    {
                        // Colors all the new nodes on the map, with the node color
                        Img.SetPixel(Temp.ElementAt(i).XCoordinate, Temp.ElementAt(i).YCoordinate, Standards.NodeColor);
                    }
                }
                if (HitWall)
                {
                    // Rotates the line direction 90deegres and creates a new line of nodes, if there arent any parallellines
                    if (!ParallelLineCheck(Temp.ElementAt(Temp.Count() - (MinPixelSizeDoor)), yDirection * (-1), xDirection))
                    {
                        Nodes.Add(Temp.ElementAt(Temp.Count() - (MinPixelSizeDoor)));
                        InNodes = true;
                        IterationStorage.Push(new CreateNodesStackElement(Temp.ElementAt(Temp.Count() - (MinPixelSizeDoor)), yDirection * (-1), xDirection));
                    }
                    // same as above but rotates the other direction
                    if (!ParallelLineCheck(Temp.ElementAt(Temp.Count() - (MinPixelSizeDoor)), yDirection, xDirection * (-1)))
                    {
                        if (!InNodes)
                        {
                            Nodes.Add(Temp.ElementAt(Temp.Count() - (MinPixelSizeDoor)));
                            InNodes = true;
                        }
                        IterationStorage.Push(new CreateNodesStackElement(Temp.ElementAt(Temp.Count() - (MinPixelSizeDoor)), yDirection, xDirection * (-1)));
                    }
                }
            }
            return;
        }
Beispiel #2
0
        /// <summary>
        /// This method targets a specific node from which it searches the Xcoordinate and Ycoordinate coordinates in all four directions.
        /// When the search hits an obstacle (e.g. a wall, another important node, door or staircase) it evaluates the length from the node to the obstacle.
        /// The method detects an obstacle by a pixel color comparison.
        /// The length between two important nodes is divided by two, to share the distance equally between the nodes.
        /// When the search is done, the area of the node is calculated by multiplying the two lengths (xLength, yLength).
        /// </summary>
        /// <param name="n"> Target node. </param>
        public void CreateSquare(Bitmap Img, double PixelsPerMeter)
        {
            bool HittingSomething = false;

            int xPos = this.XCoordinate,
                yPos = this.YCoordinate;

            // Placeholders for width and height. Will be reevaluated later
            double xLength = 0,
                   yLength = 0;

            // Increases the Xcoordinate and Ycoordinate coordinates.
            for (int i = -1; i < 2; i += 2)
            {
                if (!(this is Door) && !(this is Staircase))
                {
                    // Searching Xcoordinate coordinates
                    while (!HittingSomething)
                    {
                        xPos += i;
                        // check if we hit a wall
                        if (Img.GetPixel(xPos, yPos) == Standards.Wall)
                        {
                            xLength         += Math.Abs(this.XCoordinate - xPos);
                            HittingSomething = true;
                        }
                        // check if we hit a door or staircase
                        else if (Standards.IsDoorOrStaircaseColor(Img.GetPixel(xPos, yPos)))
                        {
                            xLength         += Math.Abs(this.XCoordinate - xPos);
                            HittingSomething = true;
                        }
                        // check if we hit another node. In this case, devide the length by two
                        else if (Img.GetPixel(xPos, yPos) == Standards.ImportantNodeColor)
                        {
                            xLength         += Convert.ToDouble(Math.Abs(this.XCoordinate - xPos) / 2);
                            HittingSomething = true;
                        }
                    }
                    HittingSomething = false;
                    xPos             = this.XCoordinate;

                    // Searching Ycoordinate coordinates
                    while (!HittingSomething)
                    {
                        yPos += i;
                        // check if we hit a wall
                        if (Img.GetPixel(xPos, yPos) == Standards.Wall)
                        {
                            yLength         += Math.Abs(this.YCoordinate - yPos);
                            HittingSomething = true;
                        }
                        // check if we hit a door or staircase
                        else if (Standards.IsDoorOrStaircaseColor(Img.GetPixel(xPos, yPos)))
                        {
                            yLength         += Math.Abs(this.YCoordinate - yPos);
                            HittingSomething = true;
                        }
                        // check if we hit another node. In this case, devide the length by two
                        else if (Img.GetPixel(xPos, yPos) == Standards.ImportantNodeColor)
                        {
                            yLength         += Convert.ToDouble(Math.Abs(this.YCoordinate - yPos) / 2);
                            HittingSomething = true;
                        }
                    }
                    HittingSomething = false;
                    yPos             = this.YCoordinate;
                }
            }
            if (!(this is Door) && !(this is Staircase))
            {
                // Set the width and height for the node
                SetAreaForNode(xLength, yLength, PixelsPerMeter);
            }
        }