How can I determine whether a 2D Point is within a Polygon?

前端 未结 30 2662
醉梦人生
醉梦人生 2020-11-21 05:06

I\'m trying to create a fast 2D point inside polygon algorithm, for use in hit-testing (e.g. Polygon.contains(p:Point)). Suggestions for effective tech

30条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-21 05:50

    Here is a C# version of the answer given by nirg, which comes from this RPI professor. Note that use of the code from that RPI source requires attribution.

    A bounding box check has been added at the top. However, as James Brown points out, the main code is almost as fast as the bounding box check itself, so the bounding box check can actually slow the overall operation, in the case that most of the points you are checking are inside the bounding box. So you could leave the bounding box check out, or an alternative would be to precompute the bounding boxes of your polygons if they don't change shape too often.

    public bool IsPointInPolygon( Point p, Point[] polygon )
    {
        double minX = polygon[ 0 ].X;
        double maxX = polygon[ 0 ].X;
        double minY = polygon[ 0 ].Y;
        double maxY = polygon[ 0 ].Y;
        for ( int i = 1 ; i < polygon.Length ; i++ )
        {
            Point q = polygon[ i ];
            minX = Math.Min( q.X, minX );
            maxX = Math.Max( q.X, maxX );
            minY = Math.Min( q.Y, minY );
            maxY = Math.Max( q.Y, maxY );
        }
    
        if ( p.X < minX || p.X > maxX || p.Y < minY || p.Y > maxY )
        {
            return false;
        }
    
        // https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html
        bool inside = false;
        for ( int i = 0, j = polygon.Length - 1 ; i < polygon.Length ; j = i++ )
        {
            if ( ( polygon[ i ].Y > p.Y ) != ( polygon[ j ].Y > p.Y ) &&
                 p.X < ( polygon[ j ].X - polygon[ i ].X ) * ( p.Y - polygon[ i ].Y ) / ( polygon[ j ].Y - polygon[ i ].Y ) + polygon[ i ].X )
            {
                inside = !inside;
            }
        }
    
        return inside;
    }
    

提交回复
热议问题