Determine if a point is inside a polygon (Ray-casting Algorithm)

Typical way to tell if a point is inside a polygon:

(1) Area sum discrimination method: determine whether the area sum of the triangle formed by the target point and each side of the polygon is equal to the polygon, and if it is equal, it is inside the polygon.

(2) Angle sum discrimination method: judge whether the sum of the angle between the target point and all sides is 360 degrees, and if it is 360 degrees, it is inside the polygon.

(3) Raycasting method: draw a ray from the target point and see the number of intersections between this ray and all sides of the polygon. If there are an odd number of intersections, it is inside, and if there is an even number of intersections, it is outside.


I haven't found a good explanation for the first two methods here. In addition, it is obvious that the third method is the best way to think, so here I only put the explanation of the third method. In addition, I remind everyone that when using the third method, you must consider the situation about vertices (for example: whether to cross a point or not; how to calculate when the ray coincides with the edge; whether the vertex may be recorded twice, etc.)

The following content is reproduced from: Click to open the link

"Judging whether a point is in a polygon" was thought to be a very difficult problem at first, but after a bit of Google, I found that it is actually quite simple. The algorithm used is called "Ray-casting Algorithm", which should be called "Ray-casting Algorithm" in Chinese. , which is described by Wikipedia: Wikipedia

Simply put, it can be judged as follows: a "ray" is drawn from this point, intersecting with any number of sides of the polygon, and the number of intersecting sides is accumulated. If it is an odd number, then the point is inside the polygon, otherwise the point is outside the polygon .

As shown in the figure, point A draws a ray, which intersects with 3 sides of the polygon, and is odd, so point A is inside the polygon, and a ray is drawn from point B, which intersects with 2 sides of the polygon, even, so point B is outside the polygon.

I plan to use this algorithm to judge whether the location on the map is within a range. I first draw a polygon area on the map with the mouse, and then use this method to judge whether a coordinate is within this polygon range. I still Take a five-pointed star as a test object and trace a five-pointed star on the Gaode map:

Um? Why is the five-pointed star not hollowed out in the middle? How is this going? After research, I found that the polygon filling of the mouse tool of the Gaode map uses another set of rules, called "None Zero Mode", and the rule for judging whether a point is within the polygon becomes: From this point, a " Ray", which intersects any number of polygon edges, the count is initialized to 0, if the intersection is cut by the polygon's edge from left to right, the count is +1, if the intersection is cut by the polygon's edge from right to left, the count is -1, last check count, if 0, the point is outside the polygon, if not 0, the point is inside the polygon. Going back to the five-pointed star example, this time pay attention to the direction the polygon lines trace:

A ray is drawn from point C. The edges of the two polygons intersected by this ray are cut from left to right. The total count is 2, so point C is inside the polygon. A more vivid way to describe it is: starting from point C, keep walking in one direction, and encounter two one-way streets, both cut from your left to the right direction, count + 1, count + 1, total count So it's 2.

The algorithm is actually very simple to implement, just a few lines of code, really just a few lines of code, I use C#, you can easily change it to something else.

public static class RayCastingAlgorithm {
        public static bool IsWithin(Point pt, IList<Point> polygon, bool noneZeroMode) {
            int ptNum = polygon.Count();
            if (ptNum < 3) {
                return false;
            }
            int j = ptNum - 1;
            bool oddNodes = false;
            int zeroState = 0;
            for (int k = 0; k < ptNum; k++) {
                Point ptK = polygon[k];
                Point ptJ = polygon[j];
                if (((ptK.Y > pt.Y) != (ptJ.Y > pt.Y)) && (pt.X < (ptJ.X - ptK.X) * (pt.Y - ptK.Y) / (ptJ.Y - ptK.Y) + ptK.X)) {
                    oddNodes =! oddNodes;
                    if (ptK.Y > ptJ.Y) {
                        zeroState ++;
                    }
                    else {
                        zeroState--;
                    }
                }
                j = k;
            }
            return noneZeroMode?zeroState!=0:oddNodes;
        }
    }


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324663965&siteId=291194637