关于极角排序:
1:在平面内取一个定点O,叫极点,引一条射线Ox,叫做极轴,再选定一个长度单位和角度的正方向(通常取逆时针方向)。
2:对于平面内任何一点M,用ρ表示线段OM的长度(有时也用r表示),θ表示从Ox到OM的角度,ρ叫做点M的极径,θ叫做点M的极角,有序数对 (ρ,θ)就叫点M的极坐标。
3:那么给定平面上的一些点,把它们按照一个选定的中心点排成顺(逆)时针
struct point//存储点
{
double x,y;
};
double cross(double x1,double y1,double x2,double y2) //计算叉积
{
return (x1*y2-x2*y1);
}
double compare(point a,point b,point c)//计算极角
{
return cross((b.x-a.x),(b.y-a.y),(c.x-a.x),(c.y-a.y));
}
方法1:利用atan2()函数按极角从小到大排序。
bool cmp1(point a,point b)
{
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:利用叉积按极角从小到大排序。
bool cmp2(point a,point b)
{
point c;//原点
c.x = 0;
c.y = 0;
if(compare(c,a,b)==0)//计算叉积,函数在上面有介绍,如果叉积相等,按照X从小到大排序
return a.x<b.x;
else return compare(c,a,b)>0;
}
方法3:先按象限从小到大排序 再按极角从小到大排序
int Quadrant(point 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 cmp3(point a,point b) //先按象限从小到大排序 再按极角从小到大排序
{
if(Quadrant(a)==Quadrant(b))//返回值就是象限
return cmp1(a,b);
else Quadrant(a)<Quadrant(b);
}
参考博客:https://www.cnblogs.com/LGJC1314/p/7235360.html
https://www.cnblogs.com/aiguona/p/7248311.html