914
搜狐
hdu 1756 Cupid's Arrow 計算幾何
判斷點是否在多邊形內部
對於任意四邊形,可以隨機選取一條射線向外延伸,如果相交邊數為奇數,則在內,偶數,則在外
這題無需考慮在邊上的情況
/*
author:jxy
lang:C/C++
university:China,Xidian University
**If you need to reprint,please indicate the source**
給定n個點的坐標,這n個點依次圍成一閉合多邊形,再給一點(x,y),判斷它是否在多邊形中。
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#define INF 1E9
#define eps 1e-8
using namespace std;
struct Node
{
double x,y;
};
Node org[1000005];
Node A,B;
int n,i;
double cross(Node A, Node B, Node C)
{
return (B.x-A.x)*(C.y-A.y) - (B.y-A.y)*(C.x-A.x);
}
bool isZero(double x) {//判斷x是否接近0
return (x > 0 ? x : -x) < eps;
}
bool in()
{
int count, i = 0;
org[n] = org[0];
while (i < n)
{
B.x = rand() + INF; //隨機取一個足夠遠的點B
B.y = rand() + INF; //以A為起點B為終點做射線L
for (i=count=0; i<n; ++i)
{
/*
if (isZero(cross(A,org[i],org[i+1]))&&
(org[i].x-A.x)*(org[i+1].x-A.x)<eps&&(org[i].y-A.y)*(org[i+1].y-A.y)<eps)
return 0;//點A在邊上
*/
if (isZero(cross(A, B, org[i]))) break;//點org[i]在射線AB上,停止本循環,另取B
else if (cross(org[i], org[i+1], A)*cross(org[i], B, org[i+1])>eps &&//射線與邊相交,統計交點數
cross(A, B, org[i])*cross(A, org[i+1], B)>eps) ++count;
}
}
return count & 1;
}
int main()
{
while(~scanf("%d",&n))
{
for(i=0;i<n;i++)
{
scanf("%lf%lf",&org[i].x,&org[i].y);
}
int m;
scanf("%d",&m);
while(m--)
{
scanf("%lf%lf",&A.x,&A.y);
if(in())puts("Yes");
else puts("No");
}
}
}
最後更新:2017-04-03 18:52:17