Ejemplo n.º 1
0
        // Graham's scan
        private static void eliminate(CDLL <MyPoint> start)
        {
            CDLL <MyPoint> v = start, w = start.Prev;
            bool           fwd = false;

            try
            {
                while (v.Next != start || !fwd)
                {
                    if (v.Next == w)
                    {
                        fwd = true;
                    }
                    if (MyPoint.Area2(v.val, v.Next.val, v.Next.Next.val) < 0) // правый поворот
                    {
                        v = v.Next;
                    }
                    else
                    {                                       // левый поворот или прямой проход
                        v.Next.Delete();
                        v = v.Prev;
                    }
                }
            }
            catch
            {
            }
        }
Ejemplo n.º 2
0
            public void CopyInto(T[] vals, int i)
            {
                CDLL <T> node = this;

                do
                {
                    vals[i++] = node.val;       // still, implicit checkcasts at runtime
                    node      = node.next;
                } while (node != this);
            }
Ejemplo n.º 3
0
            public void PrintFwd()
            {
                CDLL <T> node = this;

                do
                {
                    Console.WriteLine(node.val);
                    node = node.next;
                } while (node != this);
                Console.WriteLine();
            }
Ejemplo n.º 4
0
            public int Size()
            {
                int      count = 0;
                CDLL <T> node  = this;

                do
                {
                    count++;
                    node = node.next;
                } while (node != this);
                return(count);
            }
Ejemplo n.º 5
0
        public static MyPoint[] convexhull(MyPoint[] pts)
        {
            // Отсортировать точки по увеличению (x, y)
            int N = pts.Length;

            Polysort.Quicksort <MyPoint>(pts);
            MyPoint left = pts[0], right = pts[N - 1];

            // Разделить на список нижних граней и верхних граней
            CDLL <MyPoint> lower = new CDLL <MyPoint>(left), upper = new CDLL <MyPoint>(left);

            for (int i = 0; i < N; i++)
            {
                double det = MyPoint.Area2(left, right, pts[i]);
                if (det > 0)
                {
                    upper = upper.Append(new CDLL <MyPoint>(pts[i]));
                }
                else if (det < 0)
                {
                    lower = lower.Prepend(new CDLL <MyPoint>(pts[i]));
                }
            }
            lower = lower.Prepend(new CDLL <MyPoint>(right));
            upper = upper.Append(new CDLL <MyPoint>(right)).Next;
            // Устранить точки не на многоуголнике
            eliminate(lower);
            eliminate(upper);

            // Устранить повторяющиеся точки
            try
            {
                if (lower.Prev.val.Equals(upper.val))
                {
                    lower.Prev.Delete();
                }
                if (upper.Prev.val.Equals(lower.val))
                {
                    upper.Prev.Delete();
                }
            }
            catch
            {
                // DO NOTHING!!! JUST SKIP ERROR
            }

            // Соединяем нижние и верхние грани
            MyPoint[] res = new MyPoint[lower.Size() + upper.Size()];
            lower.CopyInto(res, 0);
            upper.CopyInto(res, lower.Size());
            return(res);
        }
Ejemplo n.º 6
0
        public static Vec2d[] GetConvexHull(Vec2d[] pts)
        {
            // Sort points lexicographically by increasing (x, y)
            int N = pts.Length;

            quicksort(pts);
            Vec2d left = pts[0], right = pts[N - 1];
            // Partition into lower hull and upper hull
            CDLL <Vec2d> lower = new CDLL <Vec2d>(left), upper = new CDLL <Vec2d>(left);

            for (int i = 0; i < N; i++)
            {
                double det = area2(left, right, pts[i]);
                if (det > 0)
                {
                    upper = upper.Append(new CDLL <Vec2d>(pts[i]));
                }
                else if (det < 0)
                {
                    lower = lower.Prepend(new CDLL <Vec2d>(pts[i]));
                }
            }
            lower = lower.Prepend(new CDLL <Vec2d>(right));
            upper = upper.Append(new CDLL <Vec2d>(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
            Vec2d[] res = new Vec2d[lower.Size() + upper.Size()];
            lower.CopyInto(res, 0);
            upper.CopyInto(res, lower.Size());
            return(res);
        }
Ejemplo n.º 7
0
        // Graham's scan
        private static void eliminate(CDLL <Vec2d> start)
        {
            CDLL <Vec2d> v = start, w = start.Prev;
            bool         fwd = false;

            while (v.Next != start || !fwd)
            {
                if (v.Next == w)
                {
                    fwd = true;
                }
                if (area2(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;
                }
            }
        }
Ejemplo n.º 8
0
 public CDLL <T> Append(CDLL <T> elt)
 {
     elt.prev = this; elt.next = next; next.prev = elt; next = elt;
     return(elt);
 }
Ejemplo n.º 9
0
 public CDLL <T> Prepend(CDLL <T> elt)
 {
     elt.next = this; elt.prev = prev; prev.next = elt; prev = elt;
     return(elt);
 }
Ejemplo n.º 10
0
 // Delete: adjust the remaining elements, make this one point nowhere
 public void Delete()
 {
     next.prev = prev; prev.next = next;
     next      = prev = null;
 }
Ejemplo n.º 11
0
 // A new CDLL node is a one-element circular list
 public CDLL(T val)
 {
     this.val = val; next = prev = this;
 }