Exemple #1
0
 // Graham's scan
 private static void eliminate(CDLL start)
 {
     CDLL v = start, w = start.Prev;
     bool fwd = false;
     while (v.Next != start || !fwd)
     {
         if (v.Next == w)
             fwd = true;
         if (Utility.Area(v.val, v.Next.val, v.Next.Next.val) < 0) // right turn
             v = v.Next;
         else
         {                                       // left turn or straight
             v.Next.Delete();
             v = v.Prev;
         }
     }
 }
Exemple #2
0
        public static Point[] convexhull(Point[] pts)
        {
            // Sort points lexicographically by increasing (x, y)
            int N = pts.Length;
            Polysort.Quicksort(pts);
            Point left = pts[0], right = pts[N - 1];

            // Partition into lower hull and upper hull
            CDLL lower = new CDLL(left), upper = new CDLL(left);
            for (int i = 0; i < N; i++)
            {
                double det = Utility.Area(left, right, pts[i]);
                if (det > 0)
                    upper = upper.Append(new CDLL(pts[i]));
                else if (det < 0)
                    lower = lower.Prepend(new CDLL(pts[i]));
            }

            lower = lower.Prepend(new CDLL(right));
            upper = upper.Append(new CDLL(right)).Next;

            // Eliminate points not on the hull
            eliminate(lower);
            eliminate(upper);

            // Eliminate duplicate endpoints
            if (lower.Prev.val.Equals(upper.val))
                lower.Prev.Delete();
            if (upper.Prev.val.Equals(lower.val))
                upper.Prev.Delete();

            // Join the lower and upper hull
            Point[] res = new Point[lower.Size() + upper.Size()];
            lower.CopyInto(res, 0);
            upper.CopyInto(res, lower.Size());

            return res;
        }
Exemple #3
0
 public CDLL Prepend(CDLL elt)
 {
     elt.next = this; elt.prev = prev; prev.next = elt; prev = elt;
     return elt;
 }
Exemple #4
0
 // Delete: adjust the remaining elements, make this one point nowhere
 public void Delete()
 {
     next.prev = prev; prev.next = next;
     next = prev = null;
 }
Exemple #5
0
 public CDLL Append(CDLL elt)
 {
     elt.prev = this; elt.next = next; next.prev = elt; next = elt;
     return elt;
 }
Exemple #6
0
        private CDLL prev, next; // not null, except in deleted elements

        #endregion Fields

        #region Constructors

        // A new CDLL node is a one-element circular list
        public CDLL(Point val)
        {
            this.val = val; next = prev = this;
        }