您的位置:首页 > 其它

UVALive 7004(计算几何 判断点与多边形的关系)

2015-10-09 20:30 501 查看
In a 2-D plane, there are n simple polygons. Some polygons may not be convex. Each polygon has atmost k vertices. Each vertex is represented as a pair of x and y coordinates. It is known that for eachvertex (x, y), x and y are both non-negative integers that
are at most 100,000. Two polygons may haveoverlaps or even one is inside the other. Given a point P = (x p , y p ) in the plane, where x p and y p arealso non-negative integers that are at most 100,000, your task is to decide, for each polygon, whether
P is inside or outside the polygon, or on the boundary of it.

Technical Specification

• The number of polygons is bounded by 10, i.e., 0 < n ≤ 10.

• The number of vertices in a polygon is at least 3 and at most 10, i.e., 2 < k ≤ 10.
• Each coordinate in any vertex is at least 0 and at most 100,000.

Input

There are at most 10 test cases. The first line is the number of test cases. For each test case, the first

line contains three integers n, x p and y p which are the number of polygons, and the x and y coordinates

of the point P . The next n lines each contain the number of vertices and the coordinates of the vertices

of each polygon in clockwise order. Each vertex is represented by 2 integers separated by a blank. Any
two vertices are also separated by a blank.

Output

For each test case, output the relative location of P with respect to each polygon by n numbers. The

i-th number is ‘0’ if P is on the boundary of it, is ‘1’ if P is inside, but not on the boundary, of it, and
is ‘2’ if it is outside and not on the boundary of it.

Sample Input

2

3 10 5

4 2 7 10 8 10 1 1 1

3 9 2 9 10 13 2

4 2 2 2 8 8 3 3 2

1 7 3

5 0 0 5 10 10 5 5 3 10 1

Sample Output

0 1 2
2

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <set>
#include <bits/stdc++.h>
#include <queue>
#include <stack>
#include <cmath>
#define LL long long
#define INF 0x3f3f3f3f
#define RR freopen("in.txt","r",stdin)
#define WW freopen("out.txt","w",stdout)

using namespace std;

const int maxn = 20000+10;
const double eps = 1e-8;
const double PI = acos(-1.0);
int sgn(double x)
{
if(fabs(x) < eps)
return 0;
if(x < 0)
return -1;
else
return 1;
}

struct Point
{
double x,y;
Point() {}
Point(double _x,double _y)
{
x = _x;
y = _y;
}
Point operator -(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
double operator ^(const Point &b)const
{
return x * b.y - y*b.x;
}
double operator *(const Point &b)const
{
return x * b.x + y*b.y;
}
void transXY(double B)
{
double tx = x,ty = y;
x = tx * cos(B) - ty * sin(B);
y = tx * sin(B) + ty * cos(B);
}

};

struct Line
{
Point s,e;
Line() {}
Line(Point _s,Point _e)
{
s = _s,e = _e;
}

pair<int, Point>operator &(const Line &b)const
{
Point res = s;
if(sgn((s-e)^(b.s-b.e)) == 0)
{
if(sgn((s-b.e)^(b.s-b.e)) == 0)
{
return make_pair(0,res);
}
else return make_pair(1,res);
}
double t = ((s-b.s)^(b.s-b.e)) / ((s-e)^(b.s-b.e));
res.x += (e.x-s.x)*t;
res.y += (e.y-s.y)*t;
return make_pair(2,res);
}
};

bool inter(Line l1,Line l2)
{
return
max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x) &&
max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x) &&
max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y) &&
max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y) &&
sgn((l2.s -l1.e)^(l1.s-l1.e)) * sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&
sgn((l1.s-l2.e)^(l2.s-l2.e)) * sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;

}

bool OnSeg(Point P,Line L)
{
return sgn((L.s-P)^(L.e-P)) == 0 && sgn((P.x - L.s.x)*(P.x - L.e.x)) <= 0 && sgn( (P.y - L.s.y)*(P.y - L.e.y) ) <= 0;
}
int inPoly(Point p,Point poly[],int n)
{
int cnt = 0;
Line ray,side;
ray.s = p;
ray.e.y = p.y;
ray.e.x = -100000000000.0;

for(int i=0; i<n; i++)
{
side.s = poly[i];
side.e = poly[(i+1)%n];
if(OnSeg(p,side))
return 0;
if(sgn(side.s.y - side.e.y) == 0)
continue;
if(OnSeg(side.s,ray))
{
if(sgn(side.s.y - side.e.y) > 0)
cnt++;
}
else if(OnSeg(side.e,ray))
{
if(sgn(side.e.y - side.s.y) > 0)
cnt++;
}
else if(inter(ray,side))
cnt++;
}
if(cnt % 2 == 1)
return 1;
else
return 2;
}

Point poly[20],p;
int main()
{
//RR;
int n,T;
scanf("%d",&T);
while(T--)
{
cin>>n>>p.x>>p.y;
int t;
for(int i=0; i<n; i++)
{
scanf("%d",&t);
for(int j=0; j<t; j++)
{
cin>>poly[j].x>>poly[j].y;
}
if(i)
printf(" ");
printf("%d",inPoly(p,poly,t));
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: