Example #1
0
        // находим верхнюю левую точку
        CPoint GetTopPoint(List <CPoint> Q)
        {
            var p0 = Q[0];

            foreach (var p in Q)
            {
                if (p.Y < p0.Y)
                {
                    p0 = p;
                }
            }
            return(p0);
        }
Example #2
0
        CPoint nextHullPoint(List <CPoint> points, CPoint p)
        {
            CPoint q = p;
            int    t;

            foreach (CPoint r in points)
            {
                t = turn(p, q, r);
                if (t == TURN_RIGHT || t == TURN_NONE && dist(p, r) > dist(p, q))
                {
                    q = r;
                }
            }
            return(q);
        }
Example #3
0
        /// <summary>
        /// Convex hull scan with Graham method
        /// </summary>
        /// <param name="points">All points</param>
        /// <returns>Convex hull points</returns>
        /// <remarks>not used, becouse sometimes work not correct</remarks>
        public List <CPoint> ConvexHullScan(List <CPoint> points)
        {
            CPoint p0 = null;

            foreach (CPoint value in points)
            {
                if (p0 == null)
                {
                    p0 = value;
                }
                else
                {
                    if (p0.Y > value.Y)
                    {
                        p0 = value;
                    }
                }
            }
            List <CPoint> order = new List <CPoint>();

            foreach (CPoint value in points)
            {
                if (p0 != value)
                {
                    order.Add(value);
                }
            }

            order = MergeSort(p0, order);
            List <CPoint> result = new List <CPoint>
            {
                p0,
                order[0],
                order[1]
            };

            order.RemoveAt(0);
            order.RemoveAt(0);
            foreach (CPoint value in order)
            {
                keepLeft(result, value);
            }
            return(result);
        }
Example #4
0
        int size; // количество точек исходного множества

        // сортирует все точки множества в порядке возрастания
        // полярного угла по отнощению к р0
        CPoint[] sort(CPoint[] P)
        {
            bool t = true;

            while (t)
            {
                t = false;
                for (int j = 0; j < sizeP - 1; j++)
                {
                    if (alpha(P[j]) > alpha(P[j + 1]))
                    {
                        CPoint tmp = P[j];
                        P[j]     = P[j + 1];
                        P[j + 1] = tmp;
                        t        = true;
                    }
                    else
                    if (alpha(P[j]) == alpha(P[j + 1]))
                    {
                        if (P[j].X > P[j + 1].X)
                        {
                            for (int k = j + 2; k < sizeP; k++)
                            {
                                P[k - 1] = P[k];
                            }
                            sizeP--;
                            t = true;
                        }
                        else
                        if (P[j + 1].X > P[j].X)
                        {
                            for (int k = j + 1; k < sizeP; k++)
                            {
                                P[k - 1] = P[k];
                            }
                            sizeP--;
                            t = true;
                        }
                    }
                }
            }
            return(P);
        }
Example #5
0
 void keepLeft(List <CPoint> hull, CPoint r)
 {
     while (hull.Count > 1 && turn(hull[hull.Count - 2], hull[hull.Count - 1], r) != TURN_LEFT)
     {
         //Debug.WriteLine("Removing Point ({0}, {1}) because turning right ", hull[hull.Count - 1].X, hull[hull.Count - 1].Y);
         hull.RemoveAt(hull.Count - 1);
     }
     if (hull.Count == 0 || hull[hull.Count - 1] != r)
     {
         //Debug.WriteLine("Adding Point ({0}, {1})", r.X, r.Y);
         hull.Add(r);
     }
     //Debug.WriteLine("# Current Convex Hull #");
     //foreach (Point value in hull)
     //{
     //  Debug.WriteLine("(" + value.X + "," + value.Y + ") ");
     //}
     //Debug.WriteLine("");
     //Debug.WriteLine("");
 }
Example #6
0
        List <CPoint> MergeSort(CPoint p0, List <CPoint> arrPoint)
        {
            if (arrPoint.Count == 1)
            {
                return(arrPoint);
            }
            List <CPoint> arrSortedInt = new List <CPoint>();
            int           middle       = (int)arrPoint.Count / 2;
            List <CPoint> leftArray    = arrPoint.GetRange(0, middle);
            List <CPoint> rightArray   = arrPoint.GetRange(middle, arrPoint.Count - middle);

            leftArray  = MergeSort(p0, leftArray);
            rightArray = MergeSort(p0, rightArray);
            int leftptr  = 0;
            int rightptr = 0;

            for (int i = 0; i < leftArray.Count + rightArray.Count; i++)
            {
                if (leftptr == leftArray.Count)
                {
                    arrSortedInt.Add(rightArray[rightptr]);
                    rightptr++;
                }
                else if (rightptr == rightArray.Count)
                {
                    arrSortedInt.Add(leftArray[leftptr]);
                    leftptr++;
                }
                else if (getAngle(p0, leftArray[leftptr]) < getAngle(p0, rightArray[rightptr]))
                {
                    arrSortedInt.Add(leftArray[leftptr]);
                    leftptr++;
                }
                else
                {
                    arrSortedInt.Add(rightArray[rightptr]);
                    rightptr++;
                }
            }
            return(arrSortedInt);
        }
Example #7
0
 int turn(CPoint p, CPoint q, CPoint r)
 {
     return(((q.X - p.X) * (r.Y - p.Y) - (r.X - p.X) * (q.Y - p.Y)).CompareTo(0));
 }
Example #8
0
 // через векторное произведение определяет поворот
 //(если величина отрицательная - поворот против часовой стрелки, и наоборот)
 double angle(CPoint t0, CPoint t1, CPoint t2)
 {
     return((t1.X - t0.X) * (t2.Y - t0.Y) - (t2.X - t0.X) * (t1.Y - t0.Y));
 }
Example #9
0
        /// <summary>
        /// Convex hull scan with Graham method
        /// </summary>
        /// <param name="points">All points</param>
        /// <returns>Convex hull points</returns>
        /// <remarks>not used, becouse sometimes work not correct</remarks>
        public List <CPoint> ConvexHullScan(List <CPoint> points)
        {
            size = points.Count;

            //p0 - точка с минимальной координатой у или самая левая из таких точек при наличии совпадений
            p0 = GetTopPoint(points);
            int ind = 0;

            for (int i = 0; i < size; i++)
            {
                if (points[i].Y > p0.Y)
                {
                    p0 = points[i]; ind = i;
                }
                else
                if (points[i].Y == p0.Y && points[i].X < p0.X)
                {
                    p0 = points[i]; ind = i;
                }
            }

            //P остальные точки (все Q кроме р0)
            sizeP = size - 1;
            CPoint[] P = new CPoint[sizeP];
            int      j = 0;

            for (int i = 0; i < size; i++)
            {
                if (i != ind)
                {
                    P[j] = points[i]; j++;
                }
            }

            P = sort(P); //сортируем Р в порядке возрастания полярного угла,измеряемого
                         //против часовой стрелки относительно р0

            var res = new List <CPoint>()
            {
                p0, P[0], P[1]
            };

            CPoint[] S = new CPoint[size]; //массив, который будет содержать вершины оболочки против часовой стрелки
            S[0] = p0; S[1] = P[0]; S[2] = P[1];
            int last = 2;

            for (int i = 2; i < sizeP; i++)
            {
                while (last > 0 && angle(S[last - 1], S[last], P[i]) >= 0)
                {
                    last--;
                }
                last++;
                S[last] = P[i];
            }

            //j = 1;
            //while (j < size && (S[j].X != 0 || S[j].Y != 0)) j++;
            //CPoint[] polygon = new CPoint[j];
            //for (int i = 0; i < j; i++) polygon[i] = S[i];

            return(S.Where(x => x.X != 0 && x.Y != 0).ToList()); // it is not correct for 0:0 point
        }