+Skyline::distance (Skyline const &other, Real horizon_padding) const
+{
+ Real dummy;
+ return internal_distance (other, horizon_padding, &dummy);
+}
+
+Real
+Skyline::touching_point (Skyline const &other, Real horizon_padding) const
+{
+ Real touch;
+ internal_distance (other, horizon_padding, &touch);
+ return touch;
+}
+
+Real
+Skyline::internal_distance (Skyline const &other, Real horizon_padding, Real *touch_point) const
+{
+ if (horizon_padding == 0.0)
+ return internal_distance (other, touch_point);
+
+ // Note that it is not necessary to build a padded version of other,
+ // because the same effect can be achieved just by doubling horizon_padding.
+ Skyline padded_this = padded (horizon_padding);
+ return padded_this.internal_distance (other, touch_point);
+}
+
+Skyline
+Skyline::padded (Real horizon_padding) const
+{
+ if (horizon_padding < 0.0)
+ warning ("Cannot have negative horizon padding. Junking.");
+
+ if (horizon_padding <= 0.0)
+ return *this;
+
+ list<Building> pad_buildings;
+ for (list<Building>::const_iterator i = buildings_.begin (); i != buildings_.end (); ++i)
+ {
+ if (i->start_ > -infinity_f)
+ {
+ Real height = i->height (i->start_);
+ if (height > -infinity_f)
+ {
+ // Add the sloped building that pads the left side of the current building.
+ Real start = i->start_ - 2 * horizon_padding;
+ Real end = i->start_ - horizon_padding;
+ pad_buildings.push_back (Building (start, height - horizon_padding, height, end));
+
+ // Add the flat building that pads the left side of the current building.
+ start = i->start_ - horizon_padding;
+ end = i->start_;
+ pad_buildings.push_back (Building (start, height, height, end));
+ }
+ }
+
+ if (i->end_ < infinity_f)
+ {
+ Real height = i->height (i->end_);
+ if (height > -infinity_f)
+ {
+ // Add the flat building that pads the right side of the current building.
+ Real start = i->end_;
+ Real end = start + horizon_padding;
+ pad_buildings.push_back (Building (start, height, height, end));
+
+ // Add the sloped building that pads the right side of the current building.
+ start = end;
+ end += horizon_padding;
+ pad_buildings.push_back (Building (start, height, height - horizon_padding, end));
+ }
+ }
+ }
+
+ // The buildings may be overlapping, so resolve that.
+ list<Building> pad_skyline = internal_build_skyline (&pad_buildings);
+
+ // Merge the padding with the original, to make a new skyline.
+ Skyline padded (sky_);
+ list<Building> my_buildings = buildings_;
+ padded.buildings_.clear ();
+ internal_merge_skyline (&pad_skyline, &my_buildings, &padded.buildings_);
+ padded.normalize ();
+
+ return padded;
+}
+
+Real
+Skyline::internal_distance (Skyline const &other, Real *touch_point) const