Determine if a point is inside a polygon (arbitrary polygon)

Recently, when I looked at the source code of recast&detour, I encountered many mathematical algorithm problems, which are hereby recorded for future review.


method

Ideas:

Make a horizontal ray to the right past this point, and see that the ray intersects several edges of the polygon. If the number of sides is odd, the point is inside the polygon.

(You can also make a ray to the left, up, and down through this point)

specific:

The following judgment is made for each edge and point to see if the following two conditions are satisfied. If both are satisfied, it is defined that the edge and the ray have an intersection. Let the edge be vj->vi and the point be pt:

    1) Whether the ordinate of point pt satisfies the formula: (vi[1] > pt[1]) != (vj[1] > pt[1])

        That is, whether the pt ordinate satisfies [vj[1], vi[1] ) , if vj[1] > vi[1], then [ vi[1], vj[1] )  , that is, whether it satisfies low closing and high opening.

    2) Then judge whether the point pt is on the left side of the line where the edge is located.

        List the standard equation of the side x = ky + b, bring in the ordinate of pt to get the value of x, if it is greater than the abscissa of pt, it means that the point pt is on the left side of the line where the side is located. [There is no need to consider the equation of the horizontal line of y = b, because if the side is a horizontal line and the point is on the same line, the first condition above is not satisfied]

Icon:

As shown in the figure below, there are three special points pt1 pt2 pt3. According to the above judgment method, the conclusion in the polygon can be correctly obtained, that is, the number of edges satisfying the condition is an odd number.


    pt0 is a normal point, and the edges satisfying the condition are v0v1 v1v2 v2v3, 3.

    pt1 is a special point, and the edges satisfying the condition are v0v1 v1v2 v2v3, 3. pt1 and v1 are on the same horizontal line, v0v1 and v1v2 both satisfy the first condition (one equal, one greater, low closed and high open), and v2v3 is normally satisfied.    

    pt2 is a special point, and the edge that satisfies the condition is v2v3, 1. pt2 and v3 and v4 are on the same horizontal line, v3v4 does not meet the first condition (both are equal), and v4v5 does not meet the first condition (one is equal, one is less than).

    pt3 is a special point, and the edge that satisfies the condition is v4v5, 1. pt3 is on the same horizontal line as v5, and v5v6 does not satisfy the first condition (one equal, one less).


source code

/// All points are projected onto the xz-plane, so the y-values are ignored.
bool dtPointInPolygon(const float* pt, const float* verts, const int nverts)
{
	// TODO: Replace pnpoly with triArea2D tests?
	int i, j;
	bool c = false;
	for (i = 0, j = nverts-1; i < nverts; j = i++)
	{
		const float* vi = &verts[i*3];
		const float* vj = &verts[j*3];
		if (((vi[2] > pt[2]) != (vj[2] > pt[2])) &&
			(pt [0] <(vj [0] -vi [0]) * (pt [2] -vi [2]) / (vj [2] -vi [2]) + vi [0]))
			c = !c;
	}
	return c;
}


refer to

https://www.codeproject.com/Tips/84226/Is-a-Point-inside-a-Polygon

Guess you like

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