用于迭代容器中一系列角度的习语?

时间:2017-03-10 22:06:15

标签: c++ stl iterator geometry

假设我有

形式的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的函数。但这似乎应该是一个常见的问题,所以我想知道是否已经有一个现有的成语来解决它?

1 个答案:

答案 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