hdu 1756 判断点在多边形内 *

模板题

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 #define lson l,mid,rt<<1
  8 #define rson mid+1,r,rt<<1|1
  9 #define root 1,n,1
 10 #define mid ((l+r)>>1)
 11 #define ll long long
 12 #define cl(a) memset(a,0,sizeof(a))
 13 #define ts printf("*****\n");
 14 using namespace std;
 15 const int MAXN=199999+9;
 16 int sum[MAXN<<2],lsum[MAXN<<2],rsum[MAXN<<2];
 17 int n,m,tt;
 18 const double eps = 1e-8;
 19 const double PI = acos(-1.0);
 20 int sgn(double x)
 21 {
 22 if(fabs(x) < eps)return 0;
 23 if(x < 0)return -1;
 24 else return 1;
 25 }
 26 struct Point
 27 {
 28 double x,y;
 29 Point(){}
 30 Point(double _x,double _y)
 31 {
 32 x = _x;y = _y;
 33 }
 34 Point operator -(const Point &b)const
 35 {
 36 return Point(x - b.x,y - b.y);
 37 }
 38 //叉积
 39 double operator ^(const Point &b)const
 40 {
 41 return x*b.y - y*b.x;
 42 }
 43 //点积
 44 double operator *(const Point &b)const
 45 {
 46 return x*b.x + y*b.y;
 47 }
 48 //绕原点旋转角度B(弧度值),后x,y的变化
 49 void transXY(double B)
 50 {
 51     double tx = x,ty = y;
 52     x = tx*cos(B) - ty*sin(B);
 53     y = tx*sin(B) + ty*cos(B);
 54 }
 55 };
 56 //*判断点在线段上
 57 struct Line
 58 {
 59 Point s,e;
 60 Line(){}
 61 Line(Point _s,Point _e)
 62 {
 63 s = _s;e = _e;
 64 }
 65 //两直线相交求交点
 66 //第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交
 67 //只有第一个值为2时,交点才有意义
 68 pair<int,Point> operator &(const Line &b)const
 69 {
 70 Point res = s;
 71 if(sgn((s-e)^(b.s-b.e)) == 0)
 72 {
 73 if(sgn((s-b.e)^(b.s-b.e)) == 0)
 74 return make_pair(0,res);//重合
 75 else return make_pair(1,res);//平行
 76 }
 77 double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
 78 res.x += (e.x-s.x)*t;
 79 res.y += (e.y-s.y)*t;
 80 return make_pair(2,res);
 81 }
 82 };
 83 bool OnSeg(Point P,Line L)
 84 {
 85 return
 86 sgn((L.s-P)^(L.e-P)) == 0 &&
 87 sgn((P.x - L.s.x) * (P.x - L.e.x)) <= 0 &&
 88 sgn((P.y - L.s.y) * (P.y - L.e.y)) <= 0;
 89 }
 90 bool inter(Line l1,Line l2)
 91 {
 92 return
 93 max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
 94 max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
 95 max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
 96 max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
 97 sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&
 98 sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;
 99 }
100 //*判断点在任意多边形内
101 //射线法,poly[]的顶点数要大于等于3,点的编号0~n-1
102 //返回值
103 //-1:点在凸多边形外
104 //0:点在凸多边形边界上
105 //1:点在凸多边形内
106 int inPoly(Point p,Point poly[],int n)
107 {
108 int cnt;
109 Line ray,side;
110 cnt = 0;
111 ray.s = p;
112 ray.e.y = p.y;
113 ray.e.x = -100000000000.0;//-INF,注意取值防止越界
114 for(int i = 0;i < n;i++)
115 {
116 side.s = poly[i];
117 side.e = poly[(i+1)%n];
118 if(OnSeg(p,side))return 0;
119 //如果平行轴则不考虑
120 if(sgn(side.s.y - side.e.y) == 0)
121 continue;
122 if(OnSeg(side.s,ray))
123 {
124 if(sgn(side.s.y - side.e.y) > 0)cnt++;
125 }
126 else if(OnSeg(side.e,ray))
127 {
128 if(sgn(side.e.y - side.s.y) > 0)cnt++;
129 }
130 else if(inter(ray,side))
131 cnt++;
132 }
133 if(cnt % 2 == 1)return 1;
134 else return -1;
135 }
136 
137 Point a[MAXN],b;
138 int main()
139 {
140     int i,j,k;
141     #ifndef ONLINE_JUDGE
142     freopen("1.in","r",stdin);
143     #endif
144     while(scanf("%d",&n)!=EOF)
145     {
146         for(i=0;i<n;i++)
147         {
148             scanf("%lf%lf",&a[i].x,&a[i].y);
149         }
150         scanf("%d",&m);
151         for(i=0;i<m;i++)
152         {
153             scanf("%lf%lf",&b.x,&b.y);
154             if(inPoly(b,a,n)!=-1)
155             {
156                 printf("Yes\n");
157             }
158             else   printf("No\n");
159         }
160     }
161 }

 

posted @ 2015-07-27 15:49  miao_a_miao  阅读(144)  评论(0编辑  收藏  举报