void precompute (Real max_slope);
Building (Real start, Real start_height, Real end_height, Real end, Real max_slope);
+ void print () const;
Real height (Real x) const;
Real intersection (Building const &other) const;
vector<Offset> to_points () const;
void merge (Skyline const &);
void insert (Box const &, Axis);
+ void print () const;
void raise (Real);
Real distance (Skyline const &) const;
Real height (Real airplane) const;
return abs (x - y) < EPS || (isinf (x) && isinf (y) && ((x > 0) == (y > 0)));
}
+void
+Skyline::print () const
+{
+ for (list<Building>::const_iterator i = buildings_.begin ();
+ i != buildings_.end (); i++)
+ {
+ (*i).print ();
+ }
+}
+
bool
Skyline::is_legal_skyline () const
{
slope_ = 0;
if (isinf (slope_) || isnan (slope_))
slope_ = max_slope * (start_height_ < end_height_ ? 1 : -1);
- assert (abs (slope_) <= max_slope);
+#if 0
+ /*
+ this check is sensitive to roundoff errors when converting to/from
+ sequences of points.
+ */
+ assert (abs (slope_) <= max_slope + EPS);
+#endif
+
if (isinf (iv_[START]))
{
if (isinf (iv_[STOP]))
return slope_*x + zero_height_;
}
+void
+Building::print () const
+{
+ printf ("X[%f,%f] -> Y[%f,%f]\n",
+ iv_[LEFT], iv_[RIGHT],
+ start_height_, end_height_);
+}
+
Real
Building::intersection (Building const &other) const
{
empty_skyline (&buildings_);
}
+/*
+ build skyline from a set of boxes.
-Skyline::Skyline (vector<Box> const &boxes, Axis a, Direction sky)
+ Boxes should have fatness in the horizon_axis, otherwise they are ignored.
+ */
+Skyline::Skyline (vector<Box> const &boxes, Axis horizon_axis, Direction sky)
{
list<Building> bldgs;
sky_ = sky;
for (vsize i = 0; i < boxes.size (); i++)
{
- Interval iv = boxes[i][a];
- Real height = sky * boxes[i][other_axis (a)][sky];
+ Interval iv = boxes[i][horizon_axis];
+ Real height = sky * boxes[i][other_axis (horizon_axis)][sky];
if (!iv.is_empty () && !isinf (height) && !equal (iv[LEFT], iv[RIGHT]))
bldgs.push_front (Building (iv[LEFT], height, height, iv[RIGHT], 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],
+ sky * points[i][Y_AXIS],
+
+ points[i][X_AXIS],
max_slope));
}
{
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_));
}