Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Suppose I have data of 2D lines in the form

struct Point { int x, y; };
struct Line {
    Point p1, p2;
    double angle() const { return atan2(p2.y-p1.y, p2.x-p1.x); }
};

And I want to store these sorted by angle, which must be in the interval (-PI, PI].

My problem: I want to iterate a range in this container, but allow it to wrap around the ends of the interval. For example "all lines between angles PI*3/4 to -PI*3/4".

To clarify, if I use standard containers like multimap, I can't simply do the usual:

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 could hack up a "circularly iterate i" function to take the place of the ++i in the loop, I guess. But this seems like it should be a common problem, so I'm wondering if there's already an existing idiom to address it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
212 views
Welcome To Ask or Share your Answers For Others

1 Answer

There is trigonometric approach to solve problems with circular ranges. For range - normalize its ends (examples here), and get middle angle and half-angle

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)

Now compare that difference of angle and range middle is lower then half-angle. Cosine solves potential troubles with periodicity, negative values etc.

if Cos(angle - mid) >= coshalf then
  angle lies in range

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...