ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HDU 1756 Cupid's Arrow 计算几何 判断一个点是否在多边形内

2020-04-30 20:53:36  阅读:280  来源: 互联网

标签:HDU return db EPS Cupid Vec Arrow operator inline


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;
}

标签:HDU,return,db,EPS,Cupid,Vec,Arrow,operator,inline
来源: https://www.cnblogs.com/chdy/p/12811098.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有