先上参考链接:
射线算法基本原理:以point为起点,无穷远为终点,作平行于x轴直线,判断多边形的每一条边与射线是否有交点,若交点总数为奇数,则点在多边形之内,若为偶数,则在多边形之外。
容易理解又很好实现,如下:
#include "opencv2/opencv.hpp"
#include <iostream>
#include <fstream>
using namespace std;
std::ifstream polygon_data("./area1.txt", std::ifstream::in);
std::vector<cv::Point2d> area;
void func()
{
double x = 0, y = 0;
while(polygon_data >> x >> y)
{
area.push_back(cv::Point2d(x, y));
}
// for (int i=0; i < area1.size(); i++)
// {
// std::cout << "x=" << area[i].x << " y=" << area[i].y << std::endl;
// std::cout << area1[i] << std::endl;
// }
}
int main()
{
func();
int nCount = area.size(); // 4
int nCross = 0;
cv::Point2d p = cv::Point2d(-10, 50);
std::cout << p << std::endl;
for (int i = 0; i < nCount; i++)
{
cv::Point2d p1 = cv::Point2d(area[i]);
// std::cout << p1<< std::endl;
cv::Point2d p2 = area[(i + 1) % nCount];
if ( p1.y == p2.y ) //p1p2与射线平行
continue;
if ( p.y < min(p1.y, p2.y) ) //射线在p1p2延长线上
continue;
if ( p.y >= max(p1.y, p2.y) ) //射线在p1p2延长线上
continue;
double x = (double)(p.y - p1.y) * (double)(p2.x - p1.x) / (double)(p2.y - p1.y) + p1.x; //p1p2与射线交点
if ( x > p.x )
nCross++;
}
std::cout << "nCross = " << nCross << std::endl;
if(nCross % 2 == 1)
std::cout << "Point is in polygon. " << std::endl;
else
std::cout << "Point is not in polygon. " << std::endl;
return 0;
}
完毕!