極角排序常用方法


極角排序常用的四種方法:

寫在前面:存儲點的結構體和函數

 

 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM