算法思想:
从待判断的点向某一个方向引射线,计算和多边形交点的个数,如果个数是偶数或者0,则点在多边形外,如果是奇数,则在多边形内。
python实现:
def is_point_in_poly(point, poly):
# 交点个数
nCross = 0
for i in range(len(poly)):
p1 = poly[i]
p2 = poly[(i + 1) % len(poly)] # 点P1与P2形成连线
if p1[1] == p2[1]:
continue
if point[1] <= min(p1[1], p2[1]):
continue
if point[1] >= max(p1[1], p2[1]):
continue
# 求交点的x坐标(由直线两点式方程转化而来)
x = (point[1] - p1[1]) * (p2[0] - p1[0]) / (p2[1] - p1[1]) + p1[0]
# 只统计p1p2与p向右射线的交点
if x > point[0]:
nCross += 1
# 交点为偶数,点在多边形之外
# 交点为奇数,点在多边形之内
if (nCross % 2) == 1:
return True
else:
return False
c++实现:
bool PtInPolygon(cv::Point p, const vector<cv::Point>& ptPolygon, int nCount)
{
// 交点个数
int nCross = 0;
for (int i = 0; i < nCount; i++)
{
cv::Point p1 = ptPolygon[i];
cv::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;
// 求交点的x坐标(由直线两点式方程转化而来)
double x = (double)(p.y - p1.y) * (double)(p2.x - p1.x) / (double)(p2.y - p1.y) + (double)p1.x;
// 只统计p1p2与p向右射线的交点
if (x > p.x)
{
nCross++;
}
}
// 交点为偶数,点在多边形之外
// 交点为奇数,点在多边形之内
if ((nCross % 2) == 1)
{
return true;
}
else
{
return false;
}
}