]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/skyline.cc
2003 -> 2004
[lilypond.git] / lily / skyline.cc
index 9857fe495506ac089005ec9054a897e1203eb151..718200c01297d1d1f935e8fd4729190ffda36e30 100644 (file)
@@ -3,7 +3,7 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  (c) 2002--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
 */
 
 #include "skyline.hh" 
@@ -38,6 +38,8 @@
  */
 
 
+const Real EPS = 1e-12;  
+
 /*
   TODO: avoid unnecessary fragmentation.
 
@@ -49,31 +51,37 @@ insert_extent_into_skyline (Array<Skyline_entry> *line, Box b, Axis line_axis,
                            Direction d)
 {
   Interval extent = b[line_axis];
-  if (extent.empty_b())
+  if (extent.is_empty ())
     return;
   
   Real stick_out = b[other_axis (line_axis)][d];
-  
+
+  /*
+    Intersect each segment of LINE with EXTENT, and if non-empty, insert relevant segments. 
+   */
   for (int i = line->size(); i--;)
     {
       Interval w = line->elem(i).width_;
-      if (extent[LEFT] > w[RIGHT])
+      w.intersect (extent);
+
+      if (extent[LEFT] >= w[RIGHT])
        break;
       
-      w.intersect (extent);
       Real my_height = line->elem(i).height_;
 
-      if (!w.empty_b () && d* (my_height - stick_out) < 0)
+      if (!w.is_empty () &&
+         w.length() > EPS
+         && d* (my_height - stick_out) < 0)
        {
          Interval e1 (line->elem(i).width_[LEFT], extent[LEFT]);
          Interval e3 (extent[RIGHT], line->elem(i).width_[RIGHT]);
 
-         if (!e3.empty_b ())
+         if (!e3.is_empty () && e3.length() > EPS)
            line->insert (Skyline_entry (e3, my_height), i+1);
 
          line->elem_ref(i).height_ = stick_out;
          line->elem_ref(i).width_ = w;
-         if (!e1.empty_b ())
+         if (!e1.is_empty () && e1.length() > EPS)
            line->insert (Skyline_entry (e1, my_height), i );
        }
 
@@ -81,6 +89,22 @@ insert_extent_into_skyline (Array<Skyline_entry> *line, Box b, Axis line_axis,
     }
 }
 
+void
+merge_skyline (Array<Skyline_entry> * a1,
+              Array<Skyline_entry> const  & a2,
+              Direction dir)
+{
+  for (int i = 0; i < a2.size(); i++)
+    {
+      Box b;
+      b[X_AXIS] = a2[i].width_;
+      b[Y_AXIS][dir] = a2[i].height_;
+      b[Y_AXIS][-dir] = dir * infinity_f ;
+
+      insert_extent_into_skyline (a1, b, X_AXIS, dir);
+    }
+}
+
 
 Array<Skyline_entry>
 empty_skyline (Direction d)
@@ -117,6 +141,7 @@ extents_to_skyline (Array<Box> const &extents, Axis a, Direction d)
 }
 
 
+
 /*
   minimum distance that can be achieved between baselines. "Clouds" is
   a skyline pointing down.
@@ -137,7 +162,7 @@ skyline_meshing_distance (Array<Skyline_entry> const &buildings,
       Interval w = buildings[i].width_;
       w.intersect(clouds[j].width_);
       
-      if (!w.empty_b())
+      if (!w.is_empty ())
        distance = distance >? (buildings[i].height_ - clouds[j].height_);
 
       if (i>0 && buildings[i].width_[LEFT] >=  clouds[j].width_[LEFT])
@@ -164,3 +189,10 @@ Skyline_entry::Skyline_entry (Interval i, Real r)
   height_ = r;
   
 }
+
+void
+heighten_skyline (Array<Skyline_entry> *buildings, Real ground)
+{
+  for (int i = 0; i < buildings->size (); i++)
+    buildings->elem_ref (i).height_ += ground; 
+}