Ejemplo n.º 1
0
    public static void GrahamScanSortingTest(List <Vector3> points, List <Vector3> ccwPolygonPoints)
    {
        if (points.Count < 3)
        {
            return;
        }
        if (points.Count == 3)
        {
            for (int i = 0; i < points.Count; i++)
            {
                ccwPolygonPoints.Add(points[i]);
            }
            return;
        }
        //find the point having the lowest y coordinate (use x for euqual cases if any)
        //put it at the end of the list and remove it (this will be point P)
        Vector3 tmp = Vector3.zero;

        for (int i = points.Count - 1; i >= 0; i--)
        {
            if (points[points.Count - 1].z > points[i].z)
            {
                //swap
                tmp = points[points.Count - 1];
                points[points.Count - 1] = points[i];
                points[i] = tmp;
            }
            else if (points[points.Count - 1].z == points[i].z)
            {
                if (points[points.Count - 1].x < points[i].x)
                {
                    tmp = points[points.Count - 1];
                    points[points.Count - 1] = points[i];
                    points[i] = tmp;
                }
            }
        }
        //sort the remaining point according the angle they form with the point P
        Vector3 P = points[points.Count - 1];

        points.RemoveAt(points.Count - 1);
        SortAlgorithms.HeapSortGrahamScan(points, ref P);
        points.Add(P);        //just a test
    }
Ejemplo n.º 2
0
    /// <summary>
    /// Performs the computation of the convex hull of the passed points
    /// through Graham scan http://en.wikipedia.org/wiki/Graham_scan
    /// the returned points are the vertices of the polygon sorted
    /// counter clockwise
    /// </summary>
    /// <param name="points"> The points of which to find the convex hull that contains them
    /// A <see cref="List<Vector3>"/>
    /// </param>
    /// <returns>
    /// A <see cref="List<Vector3>"/> The list of counter clockwise sorted vertices of the convex hull polygon
    /// </returns>
    public static List <Vector3> GrahamScan(List <Vector3> points)
    {
        List <Vector3> ccwPolygonPoints = new List <Vector3> ();

        /*
         * if(points.Count < 3)
         * {
         *      return ;
         * }
         * if(points.Count == 3)
         * {
         *      for(int i=0; i < points.Count; i++)
         *      {
         *              ccwPolygonPoints.Add(points[i]);
         *      }
         *      return ;
         * }
         */
        if (points.Count > 3)
        {
            //find the point having the lowest y coordinate (use x for euqual cases if any)
            //put it at the end of the list and remove it (this will be point P)
            Vector3 tmp = Vector3.zero;
            for (int i = points.Count - 1; i >= 0; i--)
            {
                if (points[points.Count - 1].z > points[i].z)
                {
                    //swap
                    tmp = points[points.Count - 1];
                    points[points.Count - 1] = points[i];
                    points[i] = tmp;
                }
                else if (points[points.Count - 1].z == points[i].z)
                {
                    if (points[points.Count - 1].x < points[i].x)
                    {
                        tmp = points[points.Count - 1];
                        points[points.Count - 1] = points[i];
                        points[i] = tmp;
                    }
                }
            }
            //sort the remaining point according the angle they form with the point P
            Vector3 P = points[points.Count - 1];
            points.RemoveAt(points.Count - 1);
            SortAlgorithms.HeapSortGrahamScan(points, ref P);
            ccwPolygonPoints.Add(P);
            ccwPolygonPoints.Add(points[0]);
            //points.Add(P);
            int k = 1;
            while (k < points.Count)
            {
                //Debug.Log("while graham scan");
                if (Vector3.Cross(ccwPolygonPoints[ccwPolygonPoints.Count - 1] - ccwPolygonPoints[ccwPolygonPoints.Count - 2],
                                  points[k] - ccwPolygonPoints[ccwPolygonPoints.Count - 2]).y < -SCAN_EPSILON)            //Left turn, it should be > 0  but I am using 3D coordinate using z as y axis reported in the algorithm
                {
                    ccwPolygonPoints.Add(points[k]);
                    k++;
                }
                else
                {
                    ccwPolygonPoints.RemoveAt(ccwPolygonPoints.Count - 1);
                    if (ccwPolygonPoints.Count == 1)                   //in order to make the algorithm more robust
                    {
                        ccwPolygonPoints.Add(points[k]);
                        k++;
                    }
                }
            }
        }
        else if (points.Count == 3)
        {
            for (int i = 0; i < points.Count; i++)
            {
                ccwPolygonPoints.Add(points[i]);
            }
        }
        return(ccwPolygonPoints);
    }