思路:
1、从点引出一条射线,计算与多边形交点的数量。
2、交点数量为奇数,则为内点,交点数量为偶数,则为外点。
class Solution
{
public:
/// <summary>
/// 判断点是否在多边形内部
/// </summary>
/// <param name="points">多边形点集</param>
/// <param name="p">判断点</param>
/// <returns>true:是 false:不是</returns>
bool IsInPloygon(std::vector<cv::Point2d>& points, cv::Point2d p)
{
int intersectionCount = 0;
for (int i = 0; i < points.size(); ++i)
{
cv::Point2d linePStart = points[i];
cv::Point2d linePEnd = (i == (points.size() - 1)) ? points[0] : points[i + 1];
// 点是否和线段有交点 射线方向自己设置的45°方向
if (Intersection2Segment(linePStart, linePEnd, p, cv::Point2d(1.0, 1.0)))
{
intersectionCount++;
}
}
return intersectionCount % 2 == 1;
}
private:
double Cross(cv::Point2d a, cv::Point2d b)//叉积
{
return a.x * b.y - b.x * a.y;
}
/// <summary>
/// 射线与线段是否存在交点
/// </summary>
/// <param name="line1Start">线段起点</param>
/// <param name="line1End">线段终点</param>
/// <param name="line2Start">射线起点</param>
/// <param name="line2V">射线方向</param>
/// <returns></returns>
bool Intersection2Segment(cv::Point2d line1Start, cv::Point2d line1End, cv::Point2d line2Start, cv::Point2d line2V)
{
// 判断是否平行
if (fabs(Cross(line1End - line1Start, line2V)) < 0.0001)
{
if (line2V.x * (line1Start.x - line2Start.x) >= 0 || line2V.x * (line1End.x - line2Start.x) >= 0) // 起点在线段上,有重合部分
return true;
}
else
{
if (Cross(line2Start - line1Start, line1End - line1Start) * Cross(line1End - line1Start, line2V) >= 0 &&
Cross(line1Start - line2Start, line2V) * Cross(line1End - line2Start, line2V) <= 0)
{
return true;
}
}
return false;
}
};