zoukankan      html  css  js  c++  java
  • HDU 1756 Cupid's Arrow 计算几何 判断一个点是否在多边形内

    LINK:Cupid's Arrow

    前置函数 atan2 返回一个向量的幅角.范围为[Pi,-Pi)

    值得注意的是 返回的是 相对于x轴正半轴的辐角。

    而判断一个点是否在一个多边形内 通常有三种方法:

    一种就是令这个点向多边形内所有边求角度的和 如果为2Pi 或者 -2Pi那么就在其中

    一种是射线法 看这个点引出的射线和多边形的交点个数。奇数在内部 反之在外部。

    面积判别法 看下和每条边所形成面积 是否等于多边形的面积。

    前两者都还可以用于凹多边形 第三者我不太清楚。

    这里使用的是第一种方法:

    struct Vec
    {
    	db x,y;Vec(){}Vec(db _x,db _y){x=_x;y=_y;}
    	inline Vec operator +(Vec b){return Vec(x+b.x,y+b.y);}
    	inline Vec operator -(Vec b){return Vec(x-b.x,y-b.y);}
    	inline Vec operator -(){return Vec(-x,-y);}
    	inline db operator *(Vec b){return x*b.x+y*b.y;}
    	inline db operator %(Vec b){return x*b.y-b.x*y;}
    	inline db operator ~(){return x*x+y*y;}
    	inline bool operator ==(Vec b){return fabs(x-b.x)<=EPS&&fabs(y-b.y)<=EPS;}
    	inline bool operator !=(Vec b){return fabs(x-b.x)>EPS||fabs(y-b.y)>EPS;}
    	inline Vec Unit(){db _=sq(x*x+y*y);return Vec(x/_,y/_);}
    	inline Vec Norm(){db _=sq(x*x+y*y);return Vec(-y/_,x/_);}
    	inline bool Quad(){return y>EPS||(fabs(y)<=EPS&&x>=-EPS);}
    	inline bool operator <(Vec b){return fabs(y-b.y)<=EPS?x<b.x:y<b.y;}
    };typedef Vec pt;
    inline Vec operator /(Vec a,db k){return Vec(a.x/k,a.y/k);}
    inline Vec operator *(Vec a,db k){return Vec(a.x*k,a.y*k);}
    inline Vec operator *(db k,Vec a){return Vec(a.x*k,a.y*k);}
    inline bool para(Vec a,Vec b){return fabs(a%b)<=EPS;}
    inline bool Toleft(Vec a,Vec b){return b%a>EPS;}//判断a是否在b的左边.
    inline void O(pt a,char c=' '){printf("(%.3lf,%.3lf)%c",a.x,a.y,c);}
    const int MAXN=110;
    const db Pi=acos(-1.0);
    int n,m;
    pt a[MAXN];
    inline db Angle(pt a,pt b,pt c)
    {
    	db w;b=b-c;a=a-c;w=atan2(b.y,b.x)-atan2(a.y,a.x);
    	cout<<atan2(b.y,b.x)<<endl;
    	cout<<atan2(a.y,a.x)<<endl;
    	w=w<=-Pi-EPS?w+2*Pi:w;w=w>=Pi+EPS?w-2*Pi:w;return w;
    }
    inline db sumAngle(pt c)
    {
    	db w=0;
    	rep(1,n,i)w+=Angle(a[i],a[i+1],c);
    	return w;
    }
    int main()
    {
    	freopen("1.in","r",stdin);
    	while(gt(n)==1)
    	{
    		rep(1,n,i)
    		{
    			int x,y;
    			gt(x),gt(y);
    			a[i]=Vec(x,y);
    		}
    		a[n+1]=a[1];
    		gt(m);
    		//cout<<atan2(0.0,-1.0)<<endl;
    		rep(1,m,i)
    		{
    			int x,y;
    			gt(x),gt(y);
    			db ww=sumAngle(Vec(x,y));
    			if(fabs(ww)<=EPS)puts("No");
    			else puts("Yes");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )
    BZOJ 2134: 单选错位( 期望 )
    BZOJ 1030: [JSOI2007]文本生成器( AC自动机 + dp )
    BZOJ 2599: [IOI2011]Race( 点分治 )
    BZOJ 3238: [Ahoi2013]差异( 后缀数组 + 单调栈 )
    ZOJ3732 Graph Reconstruction Havel-Hakimi定理
    HDU5653 Bomber Man wants to bomb an Array 简单DP
    HDU 5651 xiaoxin juju needs help 水题一发
    HDU 5652 India and China Origins 并查集
    HDU4725 The Shortest Path in Nya Graph dij
  • 原文地址:https://www.cnblogs.com/chdy/p/12811098.html
Copyright © 2011-2022 走看看