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;
    }
    
  • 相关阅读:

    二分查找法
    LeetCode-Two Sum III
    LeetCode-Add and Search Word
    LeetCode-Longest Substring with At Least K Repeating Characters
    LeetCode-Rearrange String k Distance Apart
    LeetCode-Game of Life
    LeetCode-Walls and Gates
    LeetCode-Water and Jug Problem
    LeetCode-Inorder Successor in BST
  • 原文地址:https://www.cnblogs.com/chdy/p/12811098.html
Copyright © 2011-2022 走看看