예제 #1
0
        /// <summary>
        /// The Graham Scan algorithm determines the points belonging to the convex hull in O(n lg n).
        /// </summary>
        /// <param name="points">set of points</param>
        /// <returns>points in the convex hull</returns>
        /// <seealso href="http://en.wikipedia.org/wiki/Graham_scan">Graham scan, Wikipedia</seealso>
        public static List <Point> GrahamScan(List <Point> points)
        {
            if (points.Count <= 3)
            {
                return(new List <Point>(points));
            }

            var ps = new List <Point>(points);

            ps.Sort(new CompareYThenX());
            ps.Sort(new PolarComparator(ps[0]));

            Deque <Point> hull = new ArrayDeque <Point>();

            hull.Push(ps[0]);
            hull.Push(ps[1]);
            hull.Push(ps[2]);

            for (int i = 3; i < points.Count; i++)
            {
                var top = hull.Pop();
                while (hull.Any() && !IsLeftTurn(hull.Peek(), top, ps[i]))
                {
                    top = hull.Pop();
                }
                hull.Push(top);
                hull.Push(ps[i]);
            }

            return(new List <Point>(hull));
        }
예제 #2
0
        /// <summary>
        /// Visits the given file, returning the {@code Event} corresponding to that
        /// visit.
        ///
        /// The {@code ignoreSecurityException} parameter determines whether
        /// any SecurityException should be ignored or not. If a SecurityException
        /// is thrown, and is ignored, then this method returns {@code null} to
        /// mean that there is no event corresponding to a visit to the file.
        ///
        /// The {@code canUseCached} parameter determines whether cached attributes
        /// for the file can be used or not.
        /// </summary>
        private Event Visit(Path entry, bool ignoreSecurityException, bool canUseCached)
        {
            // need the file attributes
            BasicFileAttributes attrs;

            try
            {
                attrs = GetAttributes(entry, canUseCached);
            }
            catch (IOException ioe)
            {
                return(new Event(EventType.ENTRY, entry, ioe));
            }
            catch (SecurityException se)
            {
                if (ignoreSecurityException)
                {
                    return(null);
                }
                throw se;
            }

            // at maximum depth or file is not a directory
            int depth = Stack.Size();

            if (depth >= MaxDepth || !attrs.Directory)
            {
                return(new Event(EventType.ENTRY, entry, attrs));
            }

            // check for cycles when following links
            if (FollowLinks && WouldLoop(entry, attrs.FileKey()))
            {
                return(new Event(EventType.ENTRY, entry, new FileSystemLoopException(entry.ToString())));
            }

            // file is a directory, attempt to open it
            DirectoryStream <Path> stream = null;

            try
            {
                stream = Files.NewDirectoryStream(entry);
            }
            catch (IOException ioe)
            {
                return(new Event(EventType.ENTRY, entry, ioe));
            }
            catch (SecurityException se)
            {
                if (ignoreSecurityException)
                {
                    return(null);
                }
                throw se;
            }

            // push a directory node to the stack and return an event
            Stack.Push(new DirectoryNode(entry, attrs.FileKey(), stream));
            return(new Event(EventType.START_DIRECTORY, entry, attrs));
        }