/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 2006--2012 Joe Neeman <joeneeman@gmail.com>
+ Copyright (C) 2006--2014 Joe Neeman <joeneeman@gmail.com>
LilyPond is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
assert (start_height == end_height);
y_intercept_ = start_height;
}
+ else if (fabs(slope_) > 1e6)
+ // too steep to be stored in slope-intercept form, given round-off error
+ {
+ slope_ = 0.0;
+ y_intercept_ = max(start_height, end_height);
+ }
else
y_intercept_ = start_height - slope_ * start;
}
}
static Real
-first_intersection (Building const &b, list<Building> *const s, Real start_x)
+first_intersection (Building const &b, list<Building> *s, Real start_x)
+/* Return the first x >= start_x where skyline s above Building b.
+ * Removes buildings from s that are concealed by b. */
{
while (!s->empty () && start_x < b.end_)
{
last_end = x;
continue;
}
-
+ // first_intersection() removes buildings from s2 if b hides them
Real end = first_intersection (b, s2, x);
if (s2->empty ())
{
break;
}
+ // Should be (end > x), during ver2.19. end == x happens fairly often,
+ // and we do not need to keep vertical segments within a skyline.
if (end >= x)
{
b.leading_part (end);
if (end >= s1->front ().end_)
s1->pop_front ();
+ // Should add during ver2.19 (to avoid an endless loop
+ // when merging identical skylines with a vertical segment)
+ // if (end >= s2->front().end_) s2->pop_front();
x = end;
}
empty_skyline (&buildings_);
}
-Skyline::Skyline (Skyline const &src)
-{
- sky_ = src.sky_;
-
- /* doesn't a list's copy constructor do this? -- jneem */
- for (list<Building>::const_iterator i = src.buildings_.begin ();
- i != src.buildings_.end (); i++)
- {
- buildings_.push_back (Building ((*i)));
- }
-}
-
Skyline::Skyline (Direction sky)
{
sky_ = sky;
sky_ = sky;
for (vsize i = 0; i < boxes.size (); i++)
- if (!boxes[i].is_empty ())
+ if (!boxes[i].is_empty (X_AXIS)
+ && !boxes[i].is_empty (Y_AXIS))
buildings.push_front (Building (boxes[i], horizon_axis, sky));
buildings_ = internal_build_skyline (&buildings);
Skyline::Skyline (Box const &b, Axis horizon_axis, Direction sky)
{
sky_ = sky;
- Building front (b, horizon_axis, sky);
- single_skyline (front, &buildings_);
- normalize ();
+ if (!b.is_empty (X_AXIS) && !b.is_empty (Y_AXIS))
+ {
+ Building front (b, horizon_axis, sky);
+ single_skyline (front, &buildings_);
+ normalize ();
+ }
}
void
}
/* do the same filtering as in Skyline (vector<Box> const&, etc.) */
- if (b.is_empty ())
+ if (b.is_empty (X_AXIS) || b.is_empty (Y_AXIS))
return;
my_bld.splice (my_bld.begin (), buildings_);