【发布时间】:2016-01-03 09:22:25
【问题描述】:
我有一个结构点:
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;
我正在尝试从vector<Point> 中找到最小元素,然后根据与该最小点的角度进行排序。
下面是相应的代码:
bool lex_yx(const Point &a, const Point &b)
{
if(a.y < b.y)
return true;
if (a.y == b.y)
return (a.x < b.x);
return false;
}
bool CalcAngRad_Compare (const Point &p_min, Point &a, Point &b)
{
Point subPt_1, subPt_2;
double a_r, b_r, a_angle, b_angle;
subPt_1 = a - p_min, subPt_2 = b - p_min;
a_angle = atan2(subPt_1.y, subPt_1.x);
b_angle = atan2(subPt_2.y, subPt_2.x);
if (a_angle < b_angle) {return true;}
if (a_angle > b_angle) {return false;}
a_r = subPt_1.x * subPt_1.x * subPt_1.y * subPt_1.y;
b_r = subPt_2.x * subPt_2.x * subPt_2.y * subPt_2.y;
return (a_r < b_r); // return (a_r <= b_r); // Code crashes, saying invalid operator <. I do not know why. Pl tell me.
}
auto it = std::min_element(V.begin(), V.end(), lex_yx);
std::sort( V.begin(), V.end(), boost::bind(CalcAngRad_Compare, *it, _1, _2));
当我传入一个简单的测试输入比如
2 2
3 3
4 4
1 1 // this should be first element in the sorted array
5 5
它有效,我得到了排序数组。但现在看看另一个简单的输入:
-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。在这种情况下,如果半径也相等,那么我return false。我试图将其更改为return (a_r <= b_r),但这似乎是不可能的。代码崩溃说无效的运算符 xutility 中,此行为true:else if (_Pred(_Right, _Left))。我不明白正在测试什么,可能检查了一些优先级。)
我希望你回答:
- 如何解决该问题并始终获得(正确)排序的向量
- 还有其他方法可以实现我正在做的事情吗?
- 我非常有兴趣了解我的思维/实施方式有什么问题?
【问题讨论】:
-
第二批输入的完整列表顺序是什么?
-
atan2的返回值可能为负数(最高为 -pi)。也许你应该在比较之前取绝对值?否则p_min的角度可能为零,但与另一点的角度可能为负,因此更小。 -
@norlesh 它包含超过 2k 个点,我已将问题最小化到这个小列表。如果解决了这个问题,整个列表就可以了..
-
@jogojapan 是的,你是对的,atan2 的范围可达 -pi,但绝对不是一个选项。它引起了其他情况..