Skyline_pair (Box const &, Axis a);
void raise (Real);
- void grow (Real);
void shift (Real);
void deholify ();
- Real smallest_shift (Skyline_pair const &other, Direction d,
- Real h_padding = 0, Real v_padding = 0);
- Real left () const;
- Real right () const;
- bool intersects (Skyline_pair const &other) const;
void insert (Box const &, Axis);
void merge (Skyline_pair const &other);
Skyline &operator [] (Direction d);
Skyline const &operator [] (Direction d) const;
- bool is_singleton () const;
bool is_empty () const;
void print () const;
void print_points () const;
void print_points () const;
void raise (Real);
void shift (Real);
- void invert ();
Real distance (Skyline const &, Real horizon_padding = 0) const;
- Real smallest_shift (Skyline const &, Direction d,
- Real horizon_padding = 0,
- Real vertical_padding = 0) const;
Real touching_point (Skyline const &, Real horizon_padding = 0) const;
Real shift_to_avoid (Skyline const &other, Real, Direction d, Real horizon_padding = 0);
Real raise_to_avoid (Skyline const &other, Real, Direction d, Real horizon_padding = 0);
void set_minimum_height (Real height);
void clear ();
bool is_empty () const;
- bool is_singleton () const;
- Real left () const;
- Real right () const;
Skyline padded (Real horizon_padding) const;
DECLARE_SCHEME_CALLBACK (get_touching_point, (SCM, SCM, SCM));
skylines_[DOWN].insert (b, a);
}
-Real
-Skyline_pair::left () const
-{
- return min (skylines_[UP].left (), skylines_[DOWN].left ());
-}
-
-Real
-Skyline_pair::right () const
-{
- return max (skylines_[UP].right (), skylines_[DOWN].right ());
-}
-
-// This function comes with the same caveats as smallest_shift:
-// if the skylines are not contiguous, we may report false
-// intersections.
-bool
-Skyline_pair::intersects (Skyline_pair const &other) const
-{
- return skylines_[UP].distance (other[DOWN]) > 0
- && other[UP].distance (skylines_[DOWN]) > 0;
-}
-
-Real
-Skyline_pair::smallest_shift (Skyline_pair const &other, Direction d,
- Real h_pad, Real v_pad)
-{
- // If skylines_[UP] avoids other[DOWN] or skylines_[DOWN] avoids
- // other[UP] then we will not intersect.
- // Note that this is not guaranteed to return the smallest shift
- // if one Skyline_pair is not connected: the smallest_shift left
- // in the case of
- // AAA
- // BBBBBB
- // AAA
- // will result in
- // AAA
- // BBBBBB
- // AAA
- // even though the originals did not collide. If it becomes necessary,
- // this case could be handled by splitting the Skyline_pairs up into
- // their connected components.
-
- return d * min (d * skylines_[UP].smallest_shift (other[DOWN], d, h_pad, v_pad),
- d * skylines_[DOWN].smallest_shift (other[UP], d, h_pad, v_pad));
-}
-
void
Skyline_pair::merge (Skyline_pair const &other)
{
&& skylines_[DOWN].is_empty ();
}
-bool
-Skyline_pair::is_singleton () const
-{
- return skylines_[UP].is_singleton ()
- && skylines_[DOWN].is_singleton ();
-}
-
Skyline &
Skyline_pair::operator [] (Direction d)
{
return dist;
}
-// changes the direction that the skyline is pointing
-void
-Skyline::invert ()
-{
- list<Building>::iterator i;
- for (i = buildings_.begin (); i != buildings_.end (); i++)
- if (!isinf (i->y_intercept_))
- {
- i->y_intercept_ *= -1;
- i->slope_ *= -1;
- }
-
- sky_ = -sky_;
-}
-
Real
Skyline::height (Real airplane) const
{
return out;
}
-// Returns the smallest (non-negative) shift in the given
-// direction which will result in THIS and OTHER not overlapping.
-// Warning: this function is O(n^2 log n). Use sparingly.
-Real
-Skyline::smallest_shift (Skyline const &other,
- Direction d,
- Real horizon_padding,
- Real vertical_padding) const
-{
- // If one or both of the paddings is zero, this can
- // be optimized...
- Skyline padded_me = padded (horizon_padding);
- padded_me.raise (vertical_padding);
-
- list<Building>::const_iterator i = padded_me.buildings_.begin ();
- list<Building>::const_iterator j = other.buildings_.begin ();
- list<Building>::const_iterator i_end = padded_me.buildings_.end ();
- list<Building>::const_iterator j_end = other.buildings_.end ();
-
- // Find all shifts that are not allowed.
- vector<Interval> forbidden_shifts;
- for (; i != i_end; ++i)
- if (i->y_intercept_ != -infinity_f)
- for (j = other.buildings_.begin (); j != j_end; ++j)
- {
- Interval iv = i->overlapping_shift_interval (*j);
- if (!iv.is_empty ())
- forbidden_shifts.push_back (iv);
- }
-
- // Now comes the trick: we want to find the smallest point
- // that is not in the union of forbidden_shifts. We can represent
- // the union of forbidden_shifts as a skyline, where a point is
- // allowed if it has height -infinity_f and forbidden otherwise.
- vector<Box> boxes;
- for (vector<Interval>::iterator k = forbidden_shifts.begin ();
- k != forbidden_shifts.end (); ++k)
- boxes.push_back (Box (*k, Interval (-1, 0)));
- Skyline s (boxes, X_AXIS, UP);
-
- // Find the smallest (ie. closest to zero, in the appropriate direction)
- // coordinate where the height of s is -infinity_f.
- Real last_good_point = -infinity_f;
- for (i = s.buildings_.begin (); i != s.buildings_.end (); ++i)
- {
- if (d == LEFT && i->start_ > 0)
- return last_good_point;
-
- if (i->y_intercept_ == -infinity_f)
- {
- if (i->start_ <= 0 && i->end_ >= 0)
- return 0;
- if (d == RIGHT && i->start_ >= 0)
- return i->start_;
-
- last_good_point = i->end_;
- }
- }
-
- return infinity_f * d;
-}
-
-Real
-Skyline::left () const
-{
- for (list<Building>::const_iterator i (buildings_.begin ());
- i != buildings_.end (); i++)
- if (i->y_intercept_ > -infinity_f)
- return i->start_;
-
- return infinity_f;
-}
-
-Real
-Skyline::right () const
-{
- for (list<Building>::const_reverse_iterator i (buildings_.rbegin ());
- i != buildings_.rend (); ++i)
- if (i->y_intercept_ > -infinity_f)
- return i->end_;
-
- return -infinity_f;
-}
-
bool
Skyline::is_empty () const
{
return b.end_ == infinity_f && b.y_intercept_ == -infinity_f;
}
-bool
-Skyline::is_singleton () const
-{
- return buildings_.size () == 3;
-}
-
void
Skyline::clear ()
{