判断点是否在多边形内部
对于任意四边形,可以随机选取一条射线向外延伸,如果相交边数为奇数,则在内,偶数,则在外
这题无需考虑在边上的情况
/*
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");
}
}
}