名词释义:
在平面内取一个定点O,叫极点,引一条射线Ox,叫做极轴,再选定一个长度单位和角度的正方向(通常取逆时针方向)。对于平面内任何一点M,用ρ表示线段OM的长度(有时也用r表示),θ表示从Ox到OM的角度,ρ叫做点M的极径,θ叫做点M的极角,有序数对 (ρ,θ)就叫点M的极坐标
极角排序有很多种方法而我认为只要会叉积一个就够了 之前长用atan2来写极角排序但是有些题目对数字精确性要高很多,所以用atan2会造成精度的损失,所以还是建议使用叉积的那种办法,毕竟在之后的凸包问题中 你还会遇到使用叉积的时候。
对了我们这里研究的极角在-π~π 上
接下来列举一下这些方法:
所有方法的前提:
定义结构体:
typedef struct P
{
double x,y;
}P;
1.利用atan2()函数按极角从小到大排序
bool cmp1(P a,P b)//在这里一定要注意 atan2函数y写在逗号前 返回的极角范围为-π~π
{
if(atan2(a.y,a.x)==atan2(b.y,b.x))
return atan2(a.y,a.x)<atan2(b.y,b.x);
else
return a.x<b.x;
}
2.利用叉积按极角从小到大排序
double compare(P a,P b,P c)
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
bool cmp2(P a,P b)
{
P c;//极点(xx,yy)
c.x=xx;
c.y=yy;
if(compare(c,a,b)==0)
return a.x<b.x;
else
return compare(c,a,b)>0;
}
3.利用complex类按极角从大到小排序:(这种方法我也没用过 也不太懂)
bool cmp3(P a,P b)
{
complex<double> c1(a.x,a.y);
complex<double> c2(b.x,b.y);
if(arg(c1)==arg(c2))
return a.x<b.x;
return arg(c1)<arg(c2);
}
在这里介绍一下 使用complex需要头文件
而 arg()函数返回的便是极角 范围也是-π~π
4.先按象限从小到大排序 再按极角从小到大排序
int Q(P a)//象限排序一定要加上坐标轴
{
if(a.x>0&&a.y>=0) return 1;
if(a.x<=0&&a.y>0) return 2;
if(a.x<0&&a.y<0) return 3;
if(a.x>0&&a.y<0) return 4;
}
bool cmp4(P a,P b)//先按象限大小排序 再按极角大小排序
{
if(Q(a)==Q(b))
return cmp1(a,b);
else
Q(a)<Q(b);
}
本文纯粹个人笔记 未经过自己一个一个套题验证 如有错误还望各位dalao指正包涵。