C++ C++;std::使用自定义函数排序
我有一个结构点:C++ C++;std::使用自定义函数排序,c++,sorting,boost,stl,std,C++,Sorting,Boost,Stl,Std,我有一个结构点: typedef struct Point { double x; double y; Point operator-(const Point &b) { Point pt; pt.x = this->x - b.x; pt.y = this->y - b.y; return pt; } friend std::ostream& oper
typedef struct Point
{
double x;
double y;
Point operator-(const Point &b)
{
Point pt;
pt.x = this->x - b.x;
pt.y = this->y - b.y;
return pt;
}
friend std::ostream& operator<<(std::ostream& os, const Point& pt)
{
return os << "X: " << pt.x << "\t\t\tY: " <<pt.y << std::endl;
}
friend std::istream& operator>>(std::istream& is, Point& pt)
{
return is >> pt.x >> pt.y;
}
}Point;
它起作用了,我得到了排序数组。但现在来看另一个简单的输入:
-0.5 -0.1
-0.1 -0.1
0 1
-1 -0.1 // this should be first element is sorted array. BUT IT IS NOT!!
5 5
我认为我没有做错什么。一个问题可能是,当y坐标相等时,角度为0或pi。在这种情况下,如果半径也相等,则I
返回false
。我尝试将其更改为返回(a\r您的第一个排序标准是由atan2
计算的角度。在您的情况下p\u min
是-1.0/-0.1。如果a
是-1.0/-0.1,b
是-0.5/-0.1,您将计算atan2(-0.1+0.1,-code>(a-p)和(-0.1+0.1,-0.5+1.0)
(b-p_min
)在这两种情况下都是0.0
。您继续比较0.0*0.0*0.0*0.0
(a
)与0.5*0.5*0.0*0.0.0
(b
),这意味着0.0.0<0.0<0.0.0
。因此a
不小于<0.1/-code>)
要计算向量之间的角度,请使用点积。| A |*| B |*cos(A和B之间的角度)=Ax*Bx+Ay*By
double len_p_min = sqrt( p_min.x*p_min.x + p_min.y*p_min.y ); // lenght of p_min
double len_a = sqrt( a.x*a.x + a.y*a.y ); // lenght of a
double len_b = sqrt( b.x*b.x + b.y*b.y ); // lenght of b
Point normalizedMin{ p_min.x / len_p_min, p_min.y / len_p_min }; // direction of p_min ( lenght == 1.0)
Point normalizedA{ a.x / len_a, a.y / len_a }; // direction of a ( lenght == 1.0)
Point normalizedB{ b.x / len_b, b.y / len_b }; // direction of b ( lenght == 1.0)
double cosAmin = normalizedMin.x*normalizedA.x + normalizedMin.y*normalizedA.y; // cos of angle between a and p_min
double angleAmin = acos( cosAmin );
double cosBmin = normalizedMin.x*normalizedB.x + normalizedMin.y*normalizedB.y; // cos of angle between b and p_min
double angleBmin = acos( cosBmin );
要比较角度,无需计算acos
。只需比较角度的cos即可
if ( fabs( cosAmin ) < fabs( cosBmin ) ) {return true;}
if ( fabs( cosAmin ) > fabs( cosbmin ) ) {return false;}
如何解决该问题并始终获得(正确)排序的向量
有没有其他方法可以实现我正在做的事情
不确定您想要的顺序,less_yx
是否执行此任务
我非常有兴趣了解我的思考/实施风格中的问题是什么
假设采用IEEE浮点算法(否则,0,0
会出现域错误)
由于您的参考点是最低的y
,传递给atan2的第二个参数为正或空
- `atan2(0, 0) = 0`
- `atan2(+x, 0) = 0`
- `atan2(x, +y) > 0`
因此,根据atan2
,任何最低的y都是等效的
a_r = subPt_1.x * subPt_1.x * subPt_1.y * subPt_1.y;
始终为subPt\u 1.y==0
。
你是说
a_r = subPt_1.x * subPt_1.x + subPt_1.y * subPt_1.y;
相反?(因此它比较x
,即使y==0
)第二批输入的列表的完整顺序是什么?atan2
的返回值可能为负值(最高为-pi)。也许你应该在比较之前取绝对值?否则,p_min
的角度可能为零,但与另一个点的角度可能为负,因此较小。@如果它包含超过2k个点,我已将问题最小化到这个小列表中。如果这个问题得到解决,整个列表就可以了。@jogojapan是的,你是对,atan2的范围高达-pi,但采用绝对值不是一个选项。它会引发其他情况。在第二个标准中,OP比较相对位置,而不是绝对位置,因此0.025<0.01
变成0==0
。我感谢您的努力。我也同意您的建议。但我们有一些东西可以针对一个特定的a进行证明算法,所以不能用acos/cos代替atan。谢谢你。我没有想到这个方法。你在金钱上是如此正确,最愚蠢的错误:a\u r
和b\u r
。纠正了这一点,问题就不复存在了。你的眼睛很好。谢谢
- `atan2(0, 0) = 0`
- `atan2(+x, 0) = 0`
- `atan2(x, +y) > 0`
a_r = subPt_1.x * subPt_1.x * subPt_1.y * subPt_1.y;
a_r = subPt_1.x * subPt_1.x + subPt_1.y * subPt_1.y;