Exemple #1
0
        public static Polygon2 Convexhull(IEnumerable <Vector2> vertices)
        {
            var pts = vertices.ToArray();

            if (!pts.Any())
            {
                return(new Polygon2());
            }



            // Sort points lexicographically by increasing (x, y)
            int n = pts.Length;

            Polysort.Quicksort(pts);


            var left  = pts[0];
            var right = pts[n - 1];

            // Partition into lower hull and upper hull
            var lower = new CircularDoublyLinkedList <Vector2>(left);
            var upper = new CircularDoublyLinkedList <Vector2>(left);

            for (int i = 0; i < n; i++)
            {
                double det = Vector2.Area2(left, right, pts[i]);
                if (det > 0)
                {
                    upper = upper.Append(new CircularDoublyLinkedList <Vector2>(pts[i]));
                }
                else if (det < 0)
                {
                    lower = lower.Prepend(new CircularDoublyLinkedList <Vector2>(pts[i]));
                }
            }
            lower = lower.Prepend(new CircularDoublyLinkedList <Vector2>(right));
            upper = upper.Append(new CircularDoublyLinkedList <Vector2>(right)).Next;
            // Eliminate points not on the hull
            Eliminate(lower);
            Eliminate(upper);
            // Eliminate duplicate endpoints
            if (lower.Prev.Value.Equals(upper.Value))
            {
                lower.Prev.Delete();
            }
            if (upper.Prev.Value.Equals(lower.Value))
            {
                upper.Prev.Delete();
            }
            // Join the lower and upper hull
            var res = new Vector2[lower.Size() + upper.Size()];

            lower.CopyInto(res, 0);
            upper.CopyInto(res, lower.Size());
            return(new Polygon2(res));
        }