AForge.Math.Geometry.GrahamConvexHull.FindHull C# (CSharp) Method

FindHull() public method

Find convex hull for the given set of points.
public FindHull ( List points ) : List
points List Set of points to search convex hull for.
return List
        public List<IntPoint> FindHull( List<IntPoint> points )
        {
            List<PointToProcess> pointsToProcess = new List<PointToProcess>( );

            // convert input points to points we can process
            foreach ( IntPoint point in points )
            {
                pointsToProcess.Add( new PointToProcess( point ) );
            }

            // find a point, with lowest X and lowest Y
            int firstCornerIndex = 0;
            PointToProcess firstCorner = pointsToProcess[0];

            for ( int i = 1, n = pointsToProcess.Count; i < n; i++ )
            {
                if ( ( pointsToProcess[i].X < firstCorner.X ) ||
                     ( ( pointsToProcess[i].X == firstCorner.X ) && ( pointsToProcess[i].Y < firstCorner.Y ) ) )
                {
                    firstCorner = pointsToProcess[i];
                    firstCornerIndex = i;
                }
            }

            // remove the just found point
            pointsToProcess.RemoveAt( firstCornerIndex );

            // find K (tangent of line's angle) and distance to the first corner
            for ( int i = 0, n = pointsToProcess.Count; i < n; i++ )
            {
                int dx = pointsToProcess[i].X - firstCorner.X;
                int dy = pointsToProcess[i].Y - firstCorner.Y;

                // don't need square root, since it is not important in our case
                pointsToProcess[i].Distance = dx * dx + dy * dy;
                // tangent of lines angle
                pointsToProcess[i].K = ( dx == 0 ) ? float.PositiveInfinity : (float) dy / dx;
            }

            // sort points by angle and distance
            pointsToProcess.Sort( );

            List<PointToProcess> convexHullTemp = new List<PointToProcess>( );

            // add first corner, which is always on the hull
            convexHullTemp.Add( firstCorner );
            // add another point, which forms a line with lowest slope
            convexHullTemp.Add( pointsToProcess[0] );
            pointsToProcess.RemoveAt( 0 );

            PointToProcess lastPoint = convexHullTemp[1];
            PointToProcess prevPoint = convexHullTemp[0];

            while ( pointsToProcess.Count != 0 )
            {
                PointToProcess newPoint = pointsToProcess[0];

                // skip any point, which has the same slope as the last one or
                // has 0 distance to the first point
                if ( ( newPoint.K == lastPoint.K ) || ( newPoint.Distance == 0 ) )
                {
                    pointsToProcess.RemoveAt( 0 );
                    continue;
                }

                // check if current point is on the left side from two last points
                if ( ( newPoint.X - prevPoint.X ) * ( lastPoint.Y - newPoint.Y ) - ( lastPoint.X - newPoint.X ) * ( newPoint.Y - prevPoint.Y ) < 0 )
                {
                    // add the point to the hull
                    convexHullTemp.Add( newPoint );
                    // and remove it from the list of points to process
                    pointsToProcess.RemoveAt( 0 );

                    prevPoint = lastPoint;
                    lastPoint = newPoint;
                }
                else
                {
                    // remove the last point from the hull
                    convexHullTemp.RemoveAt( convexHullTemp.Count - 1 );

                    lastPoint = prevPoint;
                    prevPoint = convexHullTemp[convexHullTemp.Count - 2];
                }
            }

            // convert points back
            List<IntPoint> convexHull = new List<IntPoint>( );

            foreach ( PointToProcess pt in convexHullTemp )
            {
                convexHull.Add( pt.ToPoint( ) );
            }

            return convexHull;
        }

Usage Example

Example #1
0
        // Set monochromeImage to display by the control
        public int ScanImage(Bitmap monochromeImage)
        {
            this.hulls.Clear();

            this.image = monochromeImage;

            this.blobCounter.ProcessImage(this.image);

            this.blobs = this.blobCounter.GetObjectsInformation();

            var grahamScan = new GrahamConvexHull();

            foreach (var blob in this.GetBlobs())
            {
                List<IntPoint> leftEdge;
                List<IntPoint> rightEdge;
                List<IntPoint> topEdge;
                List<IntPoint> bottomEdge;

                // collect edge points
                this.blobCounter.GetBlobsLeftAndRightEdges(blob, out leftEdge, out rightEdge);
                this.blobCounter.GetBlobsTopAndBottomEdges(blob, out topEdge, out bottomEdge);

                // find convex hull
                var edgePoints = new List<IntPoint>();
                edgePoints.AddRange(leftEdge);
                edgePoints.AddRange(rightEdge);

                List<IntPoint> hull = grahamScan.FindHull(edgePoints);
                this.hulls.Add(blob.ID, hull);
            }

            return this.blobs.Length;
        }
All Usage Examples Of AForge.Math.Geometry.GrahamConvexHull::FindHull
GrahamConvexHull