]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/beam-concave.cc
Docs makefiles: get rid of unconditional translations postprocessing
[lilypond.git] / lily / beam-concave.cc
index f0e0cbde50a384afdd67cbfff4f2f01fdc8a2946..48d45c859945eaa87ded018191bb9ab421b7b640 100644 (file)
@@ -1,19 +1,39 @@
+/* 
+  beam-concave.cc -- implement Concaveness for beams.
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2004 Han-Wen Nienhuys <hanwen@lilypond.org>
+  
+*/
+
 /*
   Determine whether a beam is concave.
 /*
   Determine whether a beam is concave.
+
+  A beam is concave when the middle notes get closer to the
+  beam than the left and right edge notes.
+
+  This is determined in two ways: by looking at the positions of the
+  middle notes, or by looking at the deviation of the inside notes
+  compared to the line connecting first and last.
+
+  The tricky thing is what to do with beams with chords. There are no
+  real guidelines in this case.
 */
 
 #include "pointer-group-interface.hh"
 */
 
 #include "pointer-group-interface.hh"
-#include "array.hh"
 #include "stem.hh"
 #include "beam.hh"
 #include "stem.hh"
 #include "beam.hh"
+#include "grob.hh"
 #include "staff-symbol-referencer.hh"
 #include "staff-symbol-referencer.hh"
+#include "directional-element-interface.hh"
 
 bool
 
 bool
-is_concave_single_notes (Array<int> const &positions, Direction beam_dir)
+is_concave_single_notes (vector<int> const &positions, Direction beam_dir)
 {
   Interval covering;
   covering.add_point (positions[0]);
 {
   Interval covering;
   covering.add_point (positions[0]);
-  covering.add_point (positions.top ());
+  covering.add_point (positions.back ());
 
   bool above = false;
   bool below = false;
 
   bool above = false;
   bool below = false;
@@ -22,7 +42,7 @@ is_concave_single_notes (Array<int> const &positions, Direction beam_dir)
   /*
     notes above and below the interval covered by 1st and last note.
   */
   /*
     notes above and below the interval covered by 1st and last note.
   */
-  for (int i = 1; i < positions.size () - 1; i++)
+  for (vsize i = 1; i + 1 < positions.size (); i++)
     {
       above = above || (positions[i] > covering[UP]);
       below = below || (positions[i] < covering[DOWN]);
     {
       above = above || (positions[i] > covering[UP]);
       below = below || (positions[i] < covering[DOWN]);
@@ -33,9 +53,9 @@ is_concave_single_notes (Array<int> const &positions, Direction beam_dir)
     A note as close or closer to the beam than begin and end, but the
     note is reached in the opposite direction as the last-first dy
   */
     A note as close or closer to the beam than begin and end, but the
     note is reached in the opposite direction as the last-first dy
   */
-  int dy = positions.top () - positions[0];
-  int closest = max (beam_dir * positions.top (), beam_dir * positions[0]);
-  for (int i = 2; !concave && i < positions.size () - 1; i++)
+  int dy = positions.back () - positions[0];
+  int closest = max (beam_dir * positions.back (), beam_dir * positions[0]);
+  for (vsize i = 2; !concave && i + 1 < positions.size (); i++)
     {
       int inner_dy = positions[i] - positions[i - 1];
       if (sign (inner_dy) != sign (dy)
     {
       int inner_dy = positions[i] - positions[i - 1];
       if (sign (inner_dy) != sign (dy)
@@ -45,7 +65,7 @@ is_concave_single_notes (Array<int> const &positions, Direction beam_dir)
     }
 
   bool all_closer = true;
     }
 
   bool all_closer = true;
-  for (int i = 1; all_closer && i < positions.size () - 1; i++)
+  for (vsize i = 1; all_closer && i + 1 < positions.size (); i++)
     {
       all_closer = all_closer
        && (beam_dir * positions[i] > closest);
     {
       all_closer = all_closer
        && (beam_dir * positions[i] > closest);
@@ -56,12 +76,12 @@ is_concave_single_notes (Array<int> const &positions, Direction beam_dir)
 }
 
 Real
 }
 
 Real
-calc_concaveness (Array<int> const &positions, Direction beam_dir)
+calc_positions_concaveness (vector<int> const &positions, Direction beam_dir)
 {
 {
-  Real dy = positions.top () - positions[0];
+  Real dy = positions.back () - positions[0];
   Real slope = dy / Real (positions.size () - 1);
   Real concaveness = 0.0;
   Real slope = dy / Real (positions.size () - 1);
   Real concaveness = 0.0;
-  for (int i = 1; i < positions.size () - 1; i++)
+  for (vsize i = 1; i + 1 < positions.size (); i++)
     {
       Real line_y = slope * i + positions[0];
 
     {
       Real line_y = slope * i + positions[0];
 
@@ -79,36 +99,37 @@ calc_concaveness (Array<int> const &positions, Direction beam_dir)
   return concaveness;
 }
 
   return concaveness;
 }
 
-MAKE_SCHEME_CALLBACK (Beam, check_concave, 1);
+
+MAKE_SCHEME_CALLBACK (Beam, calc_concaveness, 1);
 SCM
 SCM
-Beam::check_concave (SCM smob)
+Beam::calc_concaveness (SCM smob)
 {
   Grob *me = unsmob_grob (smob);
 
 {
   Grob *me = unsmob_grob (smob);
 
-  Link_array<Grob> stems
+  vector<Grob*> stems
     = extract_grob_array (me, "stems");
 
   if (is_knee (me))
     = extract_grob_array (me, "stems");
 
   if (is_knee (me))
-    return SCM_UNSPECIFIED;
+    return scm_from_double (0.0);
 
   Direction beam_dir = CENTER;
 
   Direction beam_dir = CENTER;
-  for (int i = stems.size (); i--;)
+  for (vsize i = stems.size (); i--;)
     {
     {
-      if (Stem::is_invisible (stems[i]))
-       stems.del (i);
-      else
+      if (Stem::is_normal_stem (stems[i]))
        {
        {
-         if (Direction dir = Stem::get_direction (stems[i]))
+         if (Direction dir = get_grob_direction (stems[i]))
            beam_dir = dir;
        }
            beam_dir = dir;
        }
+      else
+       stems.erase (stems.begin () + i);
     }
 
   if (stems.size () <= 2)
     }
 
   if (stems.size () <= 2)
-    return SCM_UNSPECIFIED;
+    return scm_from_int (0);
 
 
-  Array<int> close_positions;
-  Array<int> far_positions;
-  for (int i = 0; i < stems.size (); i++)
+  vector<int> close_positions;
+  vector<int> far_positions;
+  for (vsize i = 0; i < stems.size (); i++)
     {
       /*
        For chords, we take the note head that is closest to the beam.
     {
       /*
        For chords, we take the note head that is closest to the beam.
@@ -116,30 +137,27 @@ Beam::check_concave (SCM smob)
        Hmmm.. wait, for the beams in the last measure of morgenlied,
        this doesn't look so good. Let's try the heads farthest from
        the beam.
        Hmmm.. wait, for the beams in the last measure of morgenlied,
        this doesn't look so good. Let's try the heads farthest from
        the beam.
-
       */
       Interval posns = Stem::head_positions (stems[i]);
 
       */
       Interval posns = Stem::head_positions (stems[i]);
 
-      close_positions.push ((int) rint (posns[beam_dir]));
-      far_positions.push ((int) rint (posns[-beam_dir]));
+      close_positions.push_back ((int) rint (posns[beam_dir]));
+      far_positions.push_back ((int) rint (posns[-beam_dir]));
     }
 
     }
 
-  if (is_concave_single_notes (far_positions, beam_dir))
-    {
-      Drul_array<Real> pos = ly_scm2interval (me->get_property ("positions"));
-      Real r = linear_combination (pos, 0.0);
+  Real concaveness = 0.0;
 
 
-      r /= Staff_symbol_referencer::staff_space (me);
-      me->set_property ("positions", ly_interval2scm (Drul_array<Real> (r, r)));
-      me->set_property ("least-squares-dy", scm_from_double (0));
+  if (is_concave_single_notes (beam_dir == UP ? close_positions : far_positions, beam_dir))
+    {
+      concaveness = 10000;
     }
   else
     {
     }
   else
     {
-      Real concaveness = (calc_concaveness (far_positions, beam_dir)
-                         + calc_concaveness (close_positions, beam_dir)) / 2;
-
-      me->set_property ("concaveness", scm_from_double (concaveness));
+      concaveness = (calc_positions_concaveness (far_positions, beam_dir)
+                    + calc_positions_concaveness (close_positions, beam_dir)) / 2;
     }
 
     }
 
-  return SCM_UNSPECIFIED;
+  return scm_from_double (concaveness);
 }
 }
+
+
+