1. 程式人生 > >【判定點是否在多邊形內部】 ZOJ 1081

【判定點是否在多邊形內部】 ZOJ 1081

火焰之地傳送門

【題目大意】給定一個點數為 n 的多邊形,點按照順序給出,再給出 m 個點,詢問每個點是否在多邊形內。 n <= 100

大概就是用射線法判斷。特判一下三點共線。【參考部落格】

#include<bits/stdc++.h>
using namespace std;
struct point{
	int x,y;
	point(int A=0,int B=0){
		x=A,y=B;
	}
	friend inline point operator -(const point &lhs,const point &rhs){
		return point(lhs.x-rhs.x,lhs.y-rhs.y);
	}
	friend inline point operator +(const point &lhs,const point &rhs){
		return point(lhs.x+rhs.x,lhs.y+rhs.y);
	}
	friend inline int operator *(const point &lhs,const point &rhs){
		return lhs.x*rhs.y-lhs.y*rhs.x;
	}
	friend inline int dot(const point &lhs,const point &rhs){
		return lhs.x*rhs.x+lhs.y*rhs.y;
	}
}a[23333],b;
int n,m;
inline bool check(){
	int sum=0;
	for(int i=0;i<n;++i){
		int d=(b-a[i])*(a[(i+1)%n]-a[i]);
		if(d==0){
			if(dot(a[i]-b,a[(i+1)%n]-b)<=0)
				return true;
		}
        //過b向右作一條射線。
		int d1=a[i].y-b.y;
		int d2=a[(i+1)%n].y-b.y;
		//只有滿足下面的if,過b點的射線才能和這個多邊形有交點。
		if(d>0&&d1<=0&&d2>0) sum++;
		if(d<0&&d2<=0&&d1>0) sum--;
	}
	if(sum!=0) return true;
	return false;
}
int main(){
	int t=0;
	while(scanf("%d",&n)!=EOF&&n){
		t++;
		scanf("%d",&m);
		if(t!=1) putchar('\n');
		printf("Problem %d:\n",t);
		for(int i=0;i<n;++i)
			scanf("%d%d",&a[i].x,&a[i].y);
		for(int i=1;i<=m;++i){
			scanf("%d%d",&b.x,&b.y);
			if(check())
				printf("Within\n");
			else
				printf("Outside\n");
		}
	}
}