极角排序常用方法
极角排序常用的四种方法:
写在前面:存储点的结构体和函数
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精度不如叉积高。
参考博客:https://www.cnblogs.com/LGJC1314/p/7235360.html
https://www.cnblogs.com/aiguona/p/7248311.html
雪儿言