Exemple #1
0
        public Node FindUnguardedPoint(ArrayList guards)
        {
            ArrayList wallsNotVisible = (ArrayList)_walls.Clone();
            foreach (Node guard in guards)
            {
                ArrayList visibleVertices = new ArrayList();
                ArrayList tempWallsNotVisible = (ArrayList)wallsNotVisible.Clone();
                foreach (Wall wall in tempWallsNotVisible)
                {
                    if (wall != null)
                    {
                        bool fromVisible = false, toVisible = false;
                        if (IsVisible(guard, wall.From))
                        {
                            visibleVertices.Add(wall.From);
                            wall.TemporaryViewablePoint = wall.From;
                            fromVisible = true;
                        }
                        if (IsVisible(guard, wall.To))
                        {
                            wall.TemporaryViewablePoint = wall.To;
                            toVisible = true;
                        }
                        if (fromVisible && toVisible)
                        {
                            wall.TemporaryViewablePoint = null;
                            //wall.VisibleSegments.Add(new Segment(wall.From, wall.To));
                            wallsNotVisible.Remove(wall);
                        }
                    }
                }

                foreach (Node vertex in visibleVertices)
                {
                    if (vertex.Type == VertexType.Special)
                    {
                        decimal dy = guard.Y - vertex.Y;
                        decimal dx = guard.X - vertex.X;
                        decimal e = (decimal)0.0000000001;

                        Node nearNode1, nearNode2, distantNode;
                        if (Equals(guard.X, vertex.X))
                        {
                            decimal diffY = 50 * dy;
                            if (guard.Y < vertex.Y)
                            {
                                nearNode1 = new Node(guard.X, guard.Y + 5 * e);
                                nearNode2 = new Node(vertex.X, vertex.Y + 2 * e);
                                distantNode = new Node(vertex.X, vertex.Y + diffY);
                            }
                            else
                            {
                                nearNode1 = new Node(guard.X, guard.Y - 5 * e);
                                nearNode2 = new Node(vertex.X, vertex.Y - e);
                                distantNode = new Node(vertex.X, vertex.Y - diffY);

                            }
                        }
                        else
                        {
                            decimal deltaX = e * dx;
                            decimal deltaY = e * dy;
                            decimal diffX = 50 * dx;
                            decimal diffY = 50 * dy;
                            if (guard.X < vertex.X)
                            {
                                nearNode1 = new Node(guard.X + deltaX, guard.Y + 5 * deltaY);
                                nearNode2 = new Node(vertex.X + deltaX, vertex.Y + deltaY);
                                distantNode = new Node(vertex.X + diffX, vertex.Y + diffY);
                            }
                            else
                            {
                                nearNode1 = new Node(guard.X - deltaX, guard.Y - 5 * deltaY);
                                nearNode2 = new Node(vertex.X - deltaX, vertex.Y - deltaY);
                                distantNode = new Node(vertex.X - diffX, vertex.Y - diffY);
                            }
                        }

                        if (PointInPolygon(nearNode2) && PointInPolygon(nearNode1))
                        {
                            Segment extendedLine = new Segment(new Node(guard.X, guard.Y), distantNode);
                            ArrayList intersectionList = new ArrayList();
                            ArrayList intersectionWallList = new ArrayList();

                            foreach (Wall wall in _walls)
                            {
                                if (wall != null)
                                {
                                    Node intersection = Intersection(extendedLine, wall.From, wall.To);
                                    if (intersection != null && !Equals(intersection, vertex))
                                    {
                                        intersectionList.Add(intersection);
                                        intersectionWallList.Add(wall);
                                    }
                                }
                            }
                            Node nearestIntersection = GetNearestIntersection(intersectionList);
                            if (nearestIntersection != null)
                            {
                                Wall wall = intersectionWallList[intersectionList.IndexOf(nearestIntersection)] as Wall;
                                if (wall != null)
                                {
                                    if (wall.TemporaryViewablePoint == null)
                                    {
                                        wall.TemporaryViewablePoint = nearestIntersection;
                                    }
                                    else
                                    {
                                        Wall[] splitWall = SplitWall(wall, wall.TemporaryViewablePoint, nearestIntersection);
                                        ArrayList tempWallsNotVisible2 = (ArrayList)wallsNotVisible.Clone();
                                        foreach (Wall wallNotVisible in tempWallsNotVisible2)
                                        {
                                            if (IsOnLine(wallNotVisible.From, wallNotVisible.To, nearestIntersection) &&
                                                !Equals(nearestIntersection, wall.From) && !Equals(nearestIntersection, wall.To))
                                            {
                                                wallsNotVisible.Remove(wall);
                                            }
                                        }
                                        wall.TemporaryViewablePoint = null;
                                        wallsNotVisible.Remove(wall);
                                        wallsNotVisible.Add(splitWall[0]);
                                        if (splitWall[1] != null) wallsNotVisible.Add(splitWall[1]);
                                    }
                                }
                            }
                        }
                    }
                }

                foreach (Wall wall in wallsNotVisible)
                {
                    if (wall != null)
                    {
                        wall.TemporaryViewablePoint = null;
                    }
                }
            }

            if (wallsNotVisible.Count == 0)
            {
                return new Node(100000, 100000);
            }
            foreach (Wall wall in wallsNotVisible)
            {
                if (wall != null)
                {
                    Wall unguardedWall = (Wall)wallsNotVisible[0];
                    decimal x = (unguardedWall.From.X + unguardedWall.To.X) / 2;
                    decimal y = (unguardedWall.From.Y + unguardedWall.To.Y) / 2;
                    return new Node(x, y);
                }
            }
            return new Node(100000, 100000);
        }
Exemple #2
0
        private bool IsParallel(Segment segment1, Segment segment2)
        {
            bool vertical1 = false, vertical2 = false;
            decimal gradient1 = 0, gradient2 = 0;
            try
            {
                gradient1 = (segment1.To.Y - segment1.From.Y) / (segment1.To.X - segment1.From.X);
            }
            catch (Exception)
            {
                vertical1 = true;
            }

            try
            {
                gradient2 = (segment2.To.Y - segment2.From.Y) / (segment2.To.X - segment2.From.X);
            }
            catch (Exception)
            {
                vertical2 = true;
            }

            if (vertical1 && vertical2)
            {
                return true;
            }
            if (vertical1 || vertical2)
            {
                return false;
            }
            if (Equals(gradient1, gradient2))
            {
                return true;
            }
            return false;
        }
Exemple #3
0
        // TODO: Finish this function
        private Node Intersection(Segment segment1, Node from, Node to)
        {
            if (Equals(segment1.From, from) || Equals(segment1.From, to)
                || Equals(segment1.To, from) || Equals(segment1.To, to)
                || IsParallel(segment1, new Segment(from, to)))
            {
                return null;
            }

            decimal segment1X = segment1.From.X, segment1Y = segment1.From.Y;
            decimal segment1Dx = segment1.To.X - segment1.From.X, segment1Dy = segment1.To.Y - segment1.From.Y;
            decimal segment2X = to.X, segment2Y = to.Y;
            decimal segment2Dx = from.X - to.X, segment2Dy = from.Y - to.Y;

            if (Equals(segment1Dx, 0) && (from.X < segment1Y && to.X > segment1Y
                || from.X > segment1Y && to.X < segment1Y)) // Handle segment 1 is vertical
            {
                if (Equals(segment1Dx, segment2Dx))
                {
                    return null;
                }
                decimal gradient = segment2Dy / segment2Dx;
                Node node = new Node(segment1Y, segment1Y * gradient);
                if ((node.Y < segment1.From.Y && node.Y < segment1.To.Y)
                    || (node.Y > segment1.From.Y && node.Y > segment1.To.Y))
                {
                    return null;
                }
                return node;
            }
            if (Equals(segment2Dx, 0) && (from.X < segment2Y && to.X > segment2Y
                || from.X > segment2Y && to.X < segment2Y)) // Handle segment 2 is vertical
            {
                if (Equals(segment1Dx, segment2Dx))
                {
                    return null;
                }
                decimal gradient = segment1Dy / segment1Dx;
                Node node = new Node(segment2Y, segment2Y * gradient);
                if ((node.Y < from.Y && node.Y < to.Y)
                    || (node.Y > from.Y && node.Y > to.Y))
                {
                    return null;
                }
                return node;
            }

            if (!Equals(segment2Dx*segment1Dy, segment2Dy*segment1Dx))
            {
                try
                {
                    decimal t2 = (segment1Dx*(segment2Y - segment1Y) + segment1Dy*(segment1X - segment2X))/
                                 (segment2Dx*segment1Dy - segment2Dy*segment1Dx);
                    decimal t1 = (segment2X + segment2Dx*t2 - segment1X)/segment1Dx;
                    if (t2 <= 1 && t2 >= 0 && t1 >= 0 && t1 <= 1)
                    {
                        Node node = new Node(segment1X + segment1Dx*t1, segment1Y + segment1Dy*t1);
                        /*if (node == from || node == to) // TODO: If intersection is with a concave-inside vertex, ignore it (as above) - return null
                            {
                                if ((Math.Atan2((double)nextDy, (double)nextDx) >= 0 && Math.Atan2((double)previousDy, (double)previousDx) >= 0)
                                    || (Math.Atan2((double)nextDy, (double)nextDx) <= 0 && Math.Atan2((double)previousDy, (double)previousDx) <= 0))
                                { }
                                else { return null; }
                            }*/
                        return node;
                    }
                }
                catch (Exception e)
                {
                    Console.Write(e);
                }
            }
            return null;
        }