Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compute Convex Hull in C#

Tags:

c#

convex-hull

How to compute the convex hull starting from collection of points?

I am looking for an implementation of Convex hull algorithm in C#

like image 883
Owen Avatar asked Feb 03 '13 09:02

Owen


People also ask

How do you find a convex hull?

An intuitve definition is to pound nails at every point in the set S and then stretch a rubber band around the outside of these nails - the resulting image of the rubber band forms a polygonal shape called the Convex Hull.

How do you find the convex hull of an image?

CH = bwconvhull( BW ) computes the convex hull of all objects in BW and returns CH , a binary convex hull image. CH = bwconvhull( BW , method ) specifies the desired method for computing the convex hull image.

What is computing a convex hull?

Computing the convex hull means that a non-ambiguous and efficient representation of the required convex shape is constructed. The complexity of the corresponding algorithms is usually estimated in terms of n, the number of input points, and sometimes also in terms of h, the number of points on the convex hull.


1 Answers

Below is a transliteration to C# of the same Java source used in Qwertie's answer but without a dependency on non-standard classes beyond a Point class with double fields.

class ConvexHull
{
    public static double cross(Point O, Point A, Point B)
    {
        return (A.X - O.X) * (B.Y - O.Y) - (A.Y - O.Y) * (B.X - O.X);
    }

    public static List<Point> GetConvexHull(List<Point> points)
    {
        if (points == null)
            return null;

        if (points.Count() <= 1)
            return points;

        int n = points.Count(), k = 0;
        List<Point> H = new List<Point>(new Point[2 * n]);

        points.Sort((a, b) =>
             a.X == b.X ? a.Y.CompareTo(b.Y) : a.X.CompareTo(b.X));

        // Build lower hull
        for (int i = 0; i < n; ++i)
        {
            while (k >= 2 && cross(H[k - 2], H[k - 1], points[i]) <= 0)
                k--;
            H[k++] = points[i];
        }

        // Build upper hull
        for (int i = n - 2, t = k + 1; i >= 0; i--)
        {
            while (k >= t && cross(H[k - 2], H[k - 1], points[i]) <= 0)
                k--;
            H[k++] = points[i];
        }

        return H.Take(k - 1).ToList();
    }
}
like image 181
jwezorek Avatar answered Oct 24 '22 07:10

jwezorek