• 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;
    }
    
  • 相关阅读:
    输出 n 层的三角形,倒三角和叠在一起的沙漏
    求构成给定自然数的平方数的最小个数
    求一正整数约数的个数
    第一个符合要求的元素
    树枝节点之和是否等于给定值
    安装gcc
    杭电1004 ac code
    rabbitmq 笔记
    国行 lg g3 D858 刷 lg g3 D858hk 教程(备忘)
    MySQL存储过程错误No data
  • 原文地址:https://www.cnblogs.com/chdy/p/12811098.html
Copyright © 2020-2023  润新知