How to test if a point is inside of a convex polygon in 2D integer coordinates?

后端 未结 8 668
青春惊慌失措
青春惊慌失措 2020-11-30 04:05

The polygon is given as a list of Vector2I objects (2 dimensional, integer coordinates). How can i test if a given point is inside? All implementations i found on the web fa

相关标签:
8条回答
  • 2020-11-30 04:52

    Or from the man that wrote the book see - geometry page

    Specifically this page, he discusses why winding rule is generally better than ray crossing.

    edit - Sorry this isn't Jospeh O'Rourke who wrote the excellent book Computational Geometry in C, it's Paul Bourke but still a very very good source of geometry algorithms.

    0 讨论(0)
  • 2020-11-30 04:53

    If the polygon is convex, then in C#, the following implements the "test if always on same side" method, and runs at most at O(n of polygon points):

    public static bool IsInConvexPolygon(Point testPoint, List<Point> polygon)
    {
        //Check if a triangle or higher n-gon
        Debug.Assert(polygon.Length >= 3);
    
        //n>2 Keep track of cross product sign changes
        var pos = 0;
        var neg = 0;
    
        for (var i = 0; i < polygon.Count; i++)
        {
            //If point is in the polygon
            if (polygon[i] == testPoint)
                return true;
    
            //Form a segment between the i'th point
            var x1 = polygon[i].X;
            var y1 = polygon[i].Y;
    
            //And the i+1'th, or if i is the last, with the first point
            var i2 = i < polygon.Count - 1 ? i + 1 : 0;
    
            var x2 = polygon[i2].X;
            var y2 = polygon[i2].Y;
    
            var x = testPoint.X;
            var y = testPoint.Y;
    
            //Compute the cross product
            var d = (x - x1)*(y2 - y1) - (y - y1)*(x2 - x1);
    
            if (d > 0) pos++;
            if (d < 0) neg++;
    
            //If the sign changes, then point is outside
            if (pos > 0 && neg > 0)
                return false;
        }
    
        //If no change in direction, then on same side of all segments, and thus inside
        return true;
    }
    
    0 讨论(0)
提交回复
热议问题