假设我有
形式的2D线数据struct Point { int x, y; };
struct Line {
Point p1, p2;
double angle() const { return atan2(p2.y-p1.y, p2.x-p1.x); }
};
我希望按角度排序这些,这必须在(-PI, PI]
区间内。
我的问题:我想在此容器中迭代一个范围,但允许它环绕间隔的末尾。例如"角度PI*3/4
到-PI*3/4
"之间的所有线。
澄清一下,如果我使用像multimap
这样的标准容器,我就不能按照惯例做:
std::multimap<double, Line> lm;
//insert elements...
auto begin = lm.lower_bound(PI*3/4);
auto end = lm.upper_bound(-PI*3/4);
for(auto & i = begin; i != end; ++i) { //infinite loop: end is before begin!
//do stuff with i
}
我可以通过循环迭代来解决问题。我想是在循环中代替++i
的函数。但这似乎应该是一个常见的问题,所以我想知道是否已经有一个现有的成语来解决它?
答案 0 :(得分:1)
有三角学方法来解决圆形范围的问题。对于范围 - 标准化其结束(示例here),并获得中间角度和半角度
if range_end < range_start then
range_end = range_end + 2 * Pi
half = (range_end - range_start) / 2
mid = (range_end + range_start) / 2
coshalf = Cos(half)
现在比较角度和范围中间的差异低于半角度。余升用周期性,负值等解决了潜在的问题。
if Cos(angle - mid) >= coshalf then
angle lies in range