From 04e10efb0566620b4b7972d6775c8e59f04fa209 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Wed, 29 Nov 2006 21:10:33 +0100 Subject: [PATCH] skyline cleanup, and from_points, to_points functionality --- lily/include/skyline.hh | 15 ++++--- lily/skyline.cc | 98 +++++++++++++++++++++++++++++------------ lily/system.cc | 4 +- 3 files changed, 81 insertions(+), 36 deletions(-) diff --git a/lily/include/skyline.hh b/lily/include/skyline.hh index a5284fbb11..e62c2a8fc3 100644 --- a/lily/include/skyline.hh +++ b/lily/include/skyline.hh @@ -24,10 +24,10 @@ struct Building Real start_height_; Real end_height_; - /* fixme: variable naming */ - Real m_; - Real b_; + Real zero_height_; + Real slope_; + void precompute (Real max_slope); Building (Real start, Real start_height, Real end_height, Real end, Real max_slope); Real height (Real x) const; @@ -41,7 +41,8 @@ class Skyline private: list buildings_; Direction sky_; - Real max_slope_; + Real max_slope_; // fixme: not part of skyline per se? + void internal_merge_skyline (list*, list*, list *const result); void internal_build_skyline (list*, @@ -52,7 +53,8 @@ public: Skyline (); Skyline (Direction sky); Skyline (vector const &bldgs, Axis a, Direction sky); - + Skyline (vector const &points, Real max_slope, Direction sky); + vector to_points () const; void merge (Skyline const &); void insert (Box const &, Axis); void raise (Real); @@ -60,8 +62,9 @@ public: Real height (Real airplane) const; Real max_height () const; void set_minimum_height (Real height); - Stencil stencil (); }; +Stencil to_stencil (Skyline const &line); + #endif /* SKYLINE_HH */ diff --git a/lily/skyline.cc b/lily/skyline.cc index cd2cf25337..2175685ee6 100644 --- a/lily/skyline.cc +++ b/lily/skyline.cc @@ -67,7 +67,8 @@ Skyline::is_legal_skyline () const return last_x == infinity_f; } -Building::Building (Real start, Real start_height, Real end_height, Real end, Real max_slope) +Building::Building (Real start, Real start_height, Real end_height, + Real end, Real max_slope) : iv_ (start, end) { start_height_ = start_height; @@ -78,22 +79,28 @@ Building::Building (Real start, Real start_height, Real end_height, Real end, Re if (isinf (end)) assert (isinf (end_height) || start_height == end_height); - m_ = (end_height - start_height) / (end - start); - if (start_height == end_height) - m_ = 0; - if (isinf (m_) || isnan (m_)) - m_ = max_slope * (start_height < end_height ? 1 : -1); - assert (abs (m_) <= max_slope); + precompute (max_slope); +} - if (isinf (start)) +void +Building::precompute (Real max_slope) +{ + slope_ = (end_height_ - start_height_) / (iv_.length()); + if (start_height_ == end_height_) + slope_ = 0; + if (isinf (slope_) || isnan (slope_)) + slope_ = max_slope * (start_height_ < end_height_ ? 1 : -1); + assert (abs (slope_) <= max_slope); + + if (isinf (iv_[START])) { - if (isinf (end)) - b_ = start_height; + if (isinf (iv_[STOP])) + zero_height_ = start_height_; else - b_ = end_height - m_*end; + zero_height_ = end_height_ - slope_ * iv_[STOP]; } else - b_ = start_height - m_*start; + zero_height_ = start_height_ - slope_ * iv_[START]; } Real @@ -101,13 +108,13 @@ Building::height (Real x) const { if (isinf (x)) return (x > 0) ? end_height_ : start_height_; - return m_*x + b_; + return slope_*x + zero_height_; } Real Building::intersection (Building const &other) const { - return (b_ - other.b_) / (other.m_ - m_); + return (zero_height_ - other.zero_height_) / (other.slope_ - slope_); } void @@ -138,7 +145,7 @@ bool Building::obstructs (Building const &other) const { if (equal (intersection (other), iv_[LEFT]) || equal (start_height_, other.start_height_)) - return m_ > other.m_ || (m_ == other.m_ && b_ > other.b_); + return slope_ > other.slope_ || (slope_ == other.slope_ && zero_height_ > other.zero_height_); return start_height_ > other.start_height_; } @@ -236,6 +243,7 @@ Skyline::Skyline (Direction sky) empty_skyline (&buildings_); } + Skyline::Skyline (vector const &boxes, Axis a, Direction sky) { list bldgs; @@ -253,6 +261,22 @@ Skyline::Skyline (vector const &boxes, Axis a, Direction sky) assert (is_legal_skyline ()); } +Skyline::Skyline (vector const &points, Real max_slope, Direction sky) +{ + sky_ = sky; + max_slope_ = max_slope; + + for (vsize i = 1; i < points.size (); i++) + { + buildings_.push_back (Building (points[i-1][X_AXIS], sky * points[i-1][Y_AXIS], + points[i][X_AXIS], sky * points[i][Y_AXIS], + max_slope)); + + } + + assert (is_legal_skyline ()); +} + void Skyline::merge (Skyline const &other) { @@ -287,7 +311,7 @@ Skyline::raise (Real r) { i->start_height_ += sky_ * r; i->end_height_ += sky_ * r; - i->b_ += sky_ * r; + i->zero_height_ += sky_ * r; } assert (is_legal_skyline ()); } @@ -324,6 +348,7 @@ Skyline::height (Real airplane) const if (i->iv_[RIGHT] >= airplane) return sky_ * i->height (airplane); } + assert (0); return 0; } @@ -340,28 +365,45 @@ void Skyline::set_minimum_height (Real h) { Skyline s (sky_); - s.buildings_.front ().start_height_ = h*sky_; - s.buildings_.front ().end_height_ = h*sky_; - s.buildings_.front ().b_ = h*sky_; + s.buildings_.front ().start_height_ = h * sky_; + s.buildings_.front ().end_height_ = h * sky_; + s.buildings_.front ().zero_height_ = h * sky_; merge (s); } -/* - fixme: move this out of skyline. -*/ Stencil -Skyline::stencil () +to_stencil (Skyline const &line) { + vector points (line.to_points ()); + Stencil ret; - for (list::iterator i = buildings_.begin (); i != buildings_.end (); i++) + for (vsize i = 1; i < points.size (); i++) { - if (!isinf (i->iv_.length ())) + if (points[i-1].is_sane () && points[i].is_sane ()) { - Stencil line = Line_interface::make_line (0.1, - Offset (i->iv_[LEFT], sky_*i->start_height_), - Offset (i->iv_[RIGHT], sky_*i->end_height_)); + Stencil line + = Line_interface::make_line (0.1, points[i-1], points[i]); ret.add_stencil (line); } } return ret; } + +vector +Skyline::to_points () const +{ + vector out; + + bool first = true; + for (list::const_iterator i (buildings_.begin ()); + i != buildings_.end (); i++) + { + if (first) + out.push_back (Offset ((*i).iv_[LEFT], sky_ * (*i).start_height_)); + first = false; + out.push_back (Offset ((*i).iv_[RIGHT], sky_ * (*i).end_height_)); + } + + return out; +} + diff --git a/lily/system.cc b/lily/system.cc index c4fec86cb9..2a869c4501 100644 --- a/lily/system.cc +++ b/lily/system.cc @@ -402,8 +402,8 @@ System::get_paper_system () exprs)); if (debug_skylines) { - sys_stencil.add_stencil (skylines_[UP].stencil ().in_color (255, 0, 0)); - sys_stencil.add_stencil (skylines_[DOWN].stencil ().in_color (0, 255, 0)); + sys_stencil.add_stencil (to_stencil (skylines_[UP]).in_color (255, 0, 0)); + sys_stencil.add_stencil (to_stencil (skylines_[DOWN]).in_color (0, 255, 0)); } Grob *left_bound = this->get_bound (LEFT); -- 2.39.2