对于这个问题,一个最常用的算法就是,从这个点作任意射线,如果与多边形的各条边的交点是奇数个,则点在多边形内,是偶数个则表示在多边形外
以上,我不准备画各种奇形怪状的图形,然后画各种方向的射线来举证,只需要想像,你面前有一个封闭的,边缘可以任意的区域,你如果要在区域外,则进与出必须对应,有进必有出,每进或出一次,就与多边形的某条边产生一个交点,
所以只要你在区域外,进与出必须对应,产生的交点必然是2 * N次,而你要在区域内,也就是进比出要多一次,也就是交点个数是 2 * N +1。
以下代码代码中,过pt点作一条与X轴平行的射线,射线方向为左或为右都可以,算出交点
bool pointInRegion(Point pt, vector<Point> plist) { int nCross = 0; for (int i = 0; i < plist.size(); i++) { Point p1; Point p2;
//每相邻的两个点就是一条边 p1 = plist[i]; p2 = plist[(i + 1) % plist.size()];
//如果此两相邻的点与X轴平行 if (p1.y == p2.y)
{
if(p1.y == pt.y) //三点共线,则判断点是否在中间,如果在中间,则必然
{
//在两点间,则射线(不是直线)必与此多边形有一交点
if(pt.x >= min(p1.x, p2.x) && pt.x <= max(p1.x, p2.x){
nCross++;
continue;
}
}
//如果点pt不在p1 p2之间,那此时过pt的射线要么与P1 p2这条边有无数个交点 要么交点个数为0,此时不拿此边作为参考边
continue;
} //交点没在p1 p2这条边上,而在此条边的延长线上 if (pt.y < min(p1.y, p2.y)) continue; if (pt.y >= max(p1.y, p2.y)) continue;
//求出交点的坐标x, double x = (double)(pt.y - p1.y) * (double)(p2.x - p1.x) / (double)(p2.y - p1.y) + p1.x; if (x > pt.x)//统计左射线或右射线与边的交点都可以,此处统计的是右射线与多边形边的交点 nCross++; } if (nCross % 2 == 1) { return true; } else { return false; } }
原文:https://www.cnblogs.com/zengyg/p/12041462.html