大致思路是:
从这个点引一条射线,判断这条射线和多边形有几个交点,如果有奇数个交点,就在内部,否则在外部。这里是射线,我们一般选择从点开始平行于x轴正方向的射线,所以还需要判断射线和边的交点坐标,看看是不是正方向,代码如下:
#include<iostream>
#include<vector>
using namespace std;
typedef pair<double,double> PDD;
#define x first // define写错过一次!~
#define y second
bool in(vector<double> point, vector<PDD> array){
int n = array.size();
int px = point[0], py = point[1];
int cnt = 0;
for(int i=0;i<n;i++){
int j = (i+1)%n;
if(array[i].y==array[j].y){
continue; // 平行的情况,就抛弃不考虑
}
if(py>=max(array[i].y, array[j].y)){ //射线不会交叉的两种情况
continue;
}
if(py<min(array[i].y, array[j].y)) {
continue;
}
// 计算射线和这条边的交点坐标
double x = (array[i].x-array[j].x)/(array[i].y-array[j].y)*(py-array[i].y)+array[i].x;
// 如果是正方向的射线就记录下来交叉一次
if(x>px){
cnt++;
}
}
// 判断奇偶
if(cnt%2) return true;
else return false;
}
int main(){
double x,y;
cin>>x>>y;
vector<double> point={x, y};
int n;
cin>>n;
vector<PDD> array;
for(int i=0;i<n;i++){
cin>>x>>y;
array.push_back({x,y});
}
if(in(point, array)) cout<<"IN"<<endl;
else cout<<"NO"<<endl;
return 0;
}