题目链接:点击打开链接
判断点在多边形内模板题,刘汝佳白书模板。
方法是从此点向右引一条射线,判断多边形的边顺时针逆时针穿过此射线次数是否相等,相等则在外面。
注意代码中
if(k>0&&d2>=0&&d1<0) wn++;
if(k<0&&d2<0&&d1>=0) wn--; 此处d1,d2都只在一个等式中取等号,wa好几次
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#define eps 1e-8
using namespace std;
double fabs(double x){
return x>0?x:-x;
}
struct Point{
double x,y;
Point(){}
Point(double x,double y):x(x),y(y){}
Point operator - (Point obj){
return Point(x-obj.x,y-obj.y);
}
};
vector <Point > polygon;
double Cross(Point a,Point b){
return a.x*b.y-a.y*b.x;
}
int dcmp(double a){
if(fabs(a)<eps) return 0;
else if(a>0)return 1;
else return -1;
}
double Dot(Point a,Point b){
return a.x*b.x+a.y*b.y;
}
bool OnSegment(Point t,Point a,Point b){
return Cross(a-t,b-t)==0&&Dot(a-t,b-t)<=0;
}
bool InPolygon(vector <Point> v,Point t){
int wn=0;
int n=v.size();
for(int i=0;i<n;i++){
if(OnSegment(t,v[i],v[(i+1)%n]))return 0;
int k=dcmp(Cross(t-v[i],v[(i+1)%n]-v[i]));
int d1=dcmp(v[(i+1)%n].y-t.y);
int d2=dcmp(v[i].y-t.y);
if(k>0&&d2>=0&&d1<0) wn++;
if(k<0&&d2<0&&d1>=0) wn--;//d1,d2都只在一个等式中取等号
}
if(wn!=0)return 1;
return 0;
}
int N,M;
int main(){
while(~scanf("%d",&N)){
polygon.clear();
for(int i=0;i<N;i++){
double x,y;
scanf("%lf%lf",&x,&y);
polygon.push_back(Point(x,y));
}
scanf("%d",&M);
for(int j=0;j<M;j++){
double x,y;
scanf("%lf%lf",&x,&y);
Point t(x,y);
if(InPolygon(polygon,t)) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}