极角排序(主要用于凸包问题)

名词释义:

在平面内取一个定点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指正包涵。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值