极角排序常用方法

Posted weixq351

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了极角排序常用方法相关的知识,希望对你有一定的参考价值。

极角排序常用的四种方法:

写在前面:存储点的结构体和函数

 

 1 struct point//存储点
 2 {
 3     double x,y;
 4 };
 5 
 6 double cross(double x1,double y1,double x2,double y2) //计算叉积
 7 {
 8     return (x1*y2-x2*y1);
 9 }
10 
11 double compare(point a,point b,point c)//计算极角
12 {
13     return cross((b.x-a.x),(b.y-a.y),(c.x-a.x),(c.y-a.y));
14 }

 

 

方法1:利用atan2()函数按极角从小到大排序。

 

1 bool cmp1(point a,point b)
2 {
3     if(atan2(a.y,a.x)!=atan2(b.y,b.x))
4         return atan2(a.y,a.x)<atan2(b.y,b.x);
5     else return a.x<b.x;
6 }

 

 

方法2:利用叉积按极角从小到大排序。

叉积=0是指两向量平行(重合);叉积>0,则向量a在向量b的顺时针方向(可以理解为在a在b的下方);叉积<0,则向量a在向量b的逆时针方向(可以理解为在a在b的上方)。

 

1 bool cmp2(point a,point b) 
2 {
3     point c;//原点
4     c.x = 0;
5     c.y = 0;
6     if(compare(c,a,b)==0)//计算叉积,函数在上面有介绍,如果叉积相等,按照X从小到大排序
7         return a.x<b.x;
8     else return compare(c,a,b)>0;
9 }

 

 

方法3:先按象限从小到大排序 再按极角从小到大排序

 

 1 int Quadrant(point a)  //象限排序,注意包含四个坐标轴
 2 {
 3     if(a.x>0&&a.y>=0)  return 1;
 4     if(a.x<=0&&a.y>0)  return 2;
 5     if(a.x<0&&a.y<=0)  return 3;
 6     if(a.x>=0&&a.y<0)  return 4;
 7 }
 8 
 9 
10 bool cmp3(point a,point b)  //先按象限从小到大排序 再按极角从小到大排序
11 {
12     if(Quadrant(a)==Quadrant(b))//返回值就是象限
13         return cmp1(a,b);
14     else Quadrant(a)<Quadrant(b);
15 }

 

 

三种方法比较:

  第三种方法按象限从小到大排序 再按极角从小到大排序是在有特殊需求的时候才会用到。

  第一种方法,利用atan2排序,和利用叉积排序的主要区别在精度和时间上。

  具体对比:时间:相较于计算叉积,利用atan2时间快;

         精度: atan2精度不如叉积高。

 

以上是关于极角排序常用方法的主要内容,如果未能解决你的问题,请参考以下文章

极角排序详解:

poj1696(极角排序,贪心)

极角排序

poj2007(极角排序)

极角排序

极角排序