Detailed ray method of determination points within the polygon

Problem Description

A point prior p (x0, y0), polygons ptPolypon, determines whether point p within the polygon.

algorithm

Determining a point is within the polygon, we can drawn from this point a horizontal rays (rays can be arbitrary, but the level of ease of calculation), and the number of polygons observed ray intersection point, if the number of intersections is odd , the point in the polygon, if an even number is outside the polygon.

FIG points inside the polygon, from the point of doing a horizontal rays, and the number of polygon intersections is 2 * n + 1 is an odd number, the same way if the deformation of the outer multi-point is an even number.

How to determine the level of radiation and the side intersection polygons have it?
Obviously, if one edge is horizontal, then certainly there is no intersection
if (p1.y == p2.y) continue;

If the ordinate of the point p are smaller or larger than the vertical coordinates of a polygon edge, then they must be in the intersection of an extension line , the shown in FIG.

if (p.y < min(p1.y, p2.y))
            continue;
if (p.y >= max(p1.y, p2.y))
            continue;

Next we consider the general case. To determine whether there is no intersection, we only need a polygon edge equation is determined where the straight line, the ordinate y0 into point p can be obtained intersection abscissa x , compares the x and x0, if at x0 < x, the point is within the polygon in a polygonal outside and vice versa.
The formula is:

\ [X = (y0- p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + x0 \]

The complete code

struct Point
{
    double x, y;
};
bool IsInPolygon(Point p,Point *ptPolygon,int ncount)
{
    int ncross = 0;
    for (int i = 0; i < ncount; i++)
    {
        Point p1 = ptPolygon[i];
        Point p2 = ptPolygon[(i + 1) % ncount]; //相邻两条边p1,p2
        if (p1.y == p2.y)         
            continue;
        if (p.y < min(p1.y, p2.y))
            continue;
        if (p.y >= max(p1.y, p2.y))
            continue;
        double x = (p.y - p1.y)*(p2.x - p1.x) / (p2.y - p1.y) + p1.x;
        if (x > p.x)
            ncross++; //只统计单边交点
    }
    return(ncross % 2 == 1);
}

Guess you like

Origin www.cnblogs.com/muyefeiwu/p/11260366.html