- swap (s1, s2);
- swap (b, c);
- }
- // Now b, the head of s1, starts earlier or lies above s2.
-
- // Optimization: if the other skyline is empty at this point,
- // we can avoid testing some intersections. Just grab as many
- // buildings from s1 as we can, and shove them onto the output.
- if (c.y_intercept_ == -infinity_f
- && c.end_ >= b.end_)
- {
- list<Building>::iterator i = s1->begin ();
- i++;
- while (i != s1->end () && i->end_ <= c.end_)
- i++;
-
- s1->front ().start_ = last_end;
- result->splice (result->end (), *s1, s1->begin (), i);
- last_end = result->back ().end_;
- continue;
- }
- // first_intersection() removes buildings from s2 if b hides them
- Real x = first_intersection (b, s2, last_end);
- if (s2->empty ())
- break;
-
- if (x > last_end)
- {
- b.leading_part (x); // chops b, leaving the part up to x
- b.start_ = last_end;
- last_end = b.end_;
- result->push_back (b);
- }
-
- b = s1->front ();
- c = s2->front ();
- if (b.end_ <= c.end_)
- {
- // Any trailing part of b is concealed by c
- s1->pop_front ();
- // Consider c next for inclusion in the merged skyline
- s2_pending = true;
+ if (b.end_ <= b.start_) /* we are already finished with b */
+ ;
+ else if (c.above (b, c.start_)) /* -| . | */
+ {
+ Building m (b);
+ m.end_ = c.start_;
+ if (m.end_ > m.start_)
+ result->push_back (m);
+ if (b.above (c, b.end_)) /* -|\--. */
+ {
+ Building n (c);
+ n.end_ = b.start_ = b.intersection_x (c);
+ result->push_back (n);
+ result->push_back (b);
+ }
+ }
+ else
+ {
+ if (c.above (b, b.end_)) /* ---/ . | */
+ b.end_ = b.intersection_x (c);
+ else /* -----. */
+ c.start_ = b.end_;
+ result->push_back (b);
+ }
+ /* 'c' continues further, so move it into 'b' for the next pass. */
+ b = c;
+ swap (sb, sc);