示例#1
0
        /// <summary>
        /// Takes all the hull points and strings them together
        /// </summary>
        /// <param name="p_cho"></param>
        /// <returns></returns>
        private static List <Point> connectTheDots(ConvexHullObject p_cho)
        {
            List <Point> hullPoints = new List <Point>();

            //add all of Q1
            hullPoints.AddRange(p_cho.m_Q1.hullPoints);
            //remove duplicates
            if (hullPoints.Last().Equals(p_cho.m_Q4.hullPoints.First()))
            {
                hullPoints.RemoveAt(hullPoints.Count - 1);
            }

            hullPoints.AddRange(p_cho.m_Q4.hullPoints);
            if (hullPoints.Last().Equals(p_cho.m_Q3.hullPoints.First()))
            {
                hullPoints.RemoveAt(hullPoints.Count - 1);
            }

            hullPoints.AddRange(p_cho.m_Q3.hullPoints);
            if (hullPoints.Last().Equals(p_cho.m_Q2.hullPoints.First()))
            {
                hullPoints.RemoveAt(hullPoints.Count - 1);
            }

            //rinse and repeat
            hullPoints.AddRange(p_cho.m_Q2.hullPoints);
            if (hullPoints.Last().Equals(hullPoints.First()))
            {
                hullPoints.RemoveAt(hullPoints.Count - 1);
            }

            return(hullPoints);
        }
示例#2
0
        /// <summary>
        /// Using Liu and Chen's Convex shell algorithm to quicly find the outside points of the hand
        /// </summary>
        /// <param name="p_dataPoints"></param>
        /// <returns>List of hull points</returns>
        /// <seealso cref="http://www.codeproject.com/Articles/775753/A-Convex-Hull-Algorithm-and-its-implementation-in"/>
        public static List <Point> getConvexHull(List <Point> p_dataPoints)
        {
            ConvexHullObject cho = new ConvexHullObject();

            //get root points
            getRoots(p_dataPoints, ref cho);

            //Get the shell in each quadrant
            getShell(p_dataPoints, cho);

            return(connectTheDots(cho));
        }
示例#3
0
        /// <summary>
        /// prepare the data and send it off to be worked on in parallel
        /// </summary>
        /// <param name="p_dataPoints"></param>
        /// <param name="p_cho"></param>
        private static void getShell(List <Point> p_dataPoints, ConvexHullObject p_cho)
        {
            List <Point> ySortedList = p_dataPoints.OrderBy(p => p.Y).ThenBy(p => p.X).ToList();
            List <Point> xSortedList = p_dataPoints.OrderBy(p => p.X).ThenBy(p => p.Y).ToList();

            Parallel.Invoke(
                () =>
            {
                p_cho.m_Q1.evaluate(ySortedList);
            },
                () =>
            {
                p_cho.m_Q2.evaluate(ySortedList);
            },
                () =>
            {
                p_cho.m_Q3.evaluate(xSortedList);
            },
                () =>
            {
                p_cho.m_Q4.evaluate(xSortedList);
            });
        }
示例#4
0
        /// <summary>
        /// This part is to find the vertex of the extreme points thus creating 4 areas with shell points.
        /// </summary>
        /// <param name="p_dataPoints">data points to search</param>
        /// <param name="p_cho">object that stores data</param>
        private static void getRoots(List <Point> p_dataPoints, ref ConvexHullObject p_cho)
        {
            int xMin, yMin, xMax, yMax;

            xMax = yMax = 0;
            xMin = yMin = Int32.MaxValue;
            foreach (Point point in p_dataPoints)
            {
                #region Setting Left Roots
                //If this is the leftmost point set both roots Y to its Y
                if (point.X < xMin)
                {
                    //I'm worried about them having references to each other
                    // becuase they are not always the same
                    p_cho.m_Q2.xPoint = point;
                    p_cho.m_Q3.xPoint = point;

                    xMin = point.X;
                }
                //If the X point equals the min set the Y values to the extremes
                else if (point.X == xMin)
                {
                    if (point.Y < p_cho.m_Q2.xPoint.Y)
                    {
                        p_cho.m_Q2.xPoint = point;
                    }
                    else if (point.Y > p_cho.m_Q3.xPoint.Y)
                    {
                        p_cho.m_Q3.xPoint = point;
                    }
                }
                #endregion
                #region Setting Right Roots
                //If this is the rightmost point set both roots Y to its Y
                else if (point.X > xMax)
                {
                    p_cho.m_Q1.xPoint = point;
                    p_cho.m_Q4.xPoint = point;

                    xMax = point.X;
                }
                //If the X point equals the max, set the Y values to the extremes
                else if (point.X == xMax)
                {
                    if (point.Y < p_cho.m_Q1.xPoint.Y)
                    {
                        p_cho.m_Q1.xPoint = point;
                    }
                    else if (point.Y > p_cho.m_Q4.xPoint.Y)
                    {
                        p_cho.m_Q4.xPoint = point;
                    }
                }
                #endregion
                #region Setting Top Roots
                //If this is the topmost point, set both roots X to its X
                if (point.Y < yMin)
                {
                    p_cho.m_Q1.yPoint = point;
                    p_cho.m_Q2.yPoint = point;
                    yMin = point.Y;
                }
                //If the Y point equals the min, set the X values to the extremes
                else if (point.Y == yMin)
                {
                    if (point.X < p_cho.m_Q2.yPoint.X)
                    {
                        p_cho.m_Q2.yPoint = point;
                    }
                    else if (point.X > p_cho.m_Q1.yPoint.X)
                    {
                        p_cho.m_Q1.yPoint = point;
                    }
                }
                #endregion
                #region Setting Bottom Roots
                //If this is the bottommost point, set both roots X to its X
                else if (point.Y > yMax)
                {
                    p_cho.m_Q3.yPoint = point;
                    p_cho.m_Q4.yPoint = point;
                    yMax = point.Y;
                }
                //If the Y point equals the max, set the X values to the extremes
                else if (point.Y == yMax)
                {
                    if (point.X < p_cho.m_Q3.yPoint.X)
                    {
                        p_cho.m_Q3.yPoint = point;
                    }
                    else if (point.X > p_cho.m_Q4.yPoint.X)
                    {
                        p_cho.m_Q4.yPoint = point;
                    }
                }
                #endregion
            }
        }