- Building b = s1->front ();
- Building c = s2->front ();
- if (s2_pending // the head of s2 starts before the head of s1
- || c.height (last_end) > b.height (last_end))
- {
- 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;
- }
- else
- {
- // the trailing part of c is fully exposed, goes directly to merged
- s2->pop_front ();
- c.start_ = last_end;
- last_end = c.end_;
- result->push_back (c);
- }