]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/beam-concave.cc
Web: update home page.
[lilypond.git] / lily / beam-concave.cc
index ee351d0a26739d2fba275b4615cd108b3bfad33b..7ca626b60907f75aceeac1a81542adb7b0d1c372 100644 (file)
@@ -1,5 +1,34 @@
+/*
+  This file is part of LilyPond, the GNU music typesetter.
+
+  Copyright (C) 2004 Han-Wen Nienhuys <hanwen@lilypond.org>
+
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 /*
   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"
@@ -23,7 +52,7 @@ is_concave_single_notes (vector<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 (vsize 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]);
@@ -36,7 +65,7 @@ is_concave_single_notes (vector<int> const &positions, Direction beam_dir)
   */
   int dy = positions.back () - positions[0];
   int closest = max (beam_dir * positions.back (), beam_dir * positions[0]);
   */
   int dy = positions.back () - positions[0];
   int closest = max (beam_dir * positions.back (), beam_dir * positions[0]);
-  for (vsize i = 2; !concave && i < positions.size () - 1; i++)
+  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)
@@ -46,7 +75,7 @@ is_concave_single_notes (vector<int> const &positions, Direction beam_dir)
     }
 
   bool all_closer = true;
     }
 
   bool all_closer = true;
-  for (vsize 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);
@@ -62,7 +91,7 @@ calc_positions_concaveness (vector<int> const &positions, Direction beam_dir)
   Real dy = positions.back () - positions[0];
   Real slope = dy / Real (positions.size () - 1);
   Real concaveness = 0.0;
   Real dy = positions.back () - positions[0];
   Real slope = dy / Real (positions.size () - 1);
   Real concaveness = 0.0;
-  for (vsize 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];
 
@@ -96,17 +125,17 @@ Beam::calc_concaveness (SCM smob)
   Direction beam_dir = CENTER;
   for (vsize i = stems.size (); i--;)
     {
   Direction beam_dir = CENTER;
   for (vsize i = stems.size (); i--;)
     {
-      if (Stem::is_invisible (stems[i]))
-       stems.erase (stems.begin () + i);
-      else
+      if (Stem::is_normal_stem (stems[i]))
        {
          if (Direction dir = get_grob_direction (stems[i]))
            beam_dir = dir;
        }
        {
          if (Direction dir = get_grob_direction (stems[i]))
            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);
 
   vector<int> close_positions;
   vector<int> far_positions;
 
   vector<int> close_positions;
   vector<int> far_positions;
@@ -118,7 +147,6 @@ Beam::calc_concaveness (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]);
 
@@ -128,7 +156,7 @@ Beam::calc_concaveness (SCM smob)
 
   Real concaveness = 0.0;
 
 
   Real concaveness = 0.0;
 
-  if (is_concave_single_notes (far_positions, beam_dir))
+  if (is_concave_single_notes (beam_dir == UP ? close_positions : far_positions, beam_dir))
     {
       concaveness = 10000;
     }
     {
       concaveness = 10000;
     }