X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;ds=sidebyside;f=lily%2Fbeam-concave.cc;h=501b753d2108a1f858f75663865e7f03fcb67ba5;hb=b29bb82ddbf82b9989fa1f1e552491a2f6e5504a;hp=ee351d0a26739d2fba275b4615cd108b3bfad33b;hpb=d8082113a0df616e7beabc0417c3590a3fac7320;p=lilypond.git diff --git a/lily/beam-concave.cc b/lily/beam-concave.cc index ee351d0a26..501b753d21 100644 --- a/lily/beam-concave.cc +++ b/lily/beam-concave.cc @@ -1,5 +1,34 @@ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 2004 Han-Wen Nienhuys + + 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 . +*/ + /* 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" @@ -23,7 +52,7 @@ is_concave_single_notes (vector const &positions, Direction beam_dir) /* 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]); @@ -36,20 +65,20 @@ is_concave_single_notes (vector const &positions, Direction beam_dir) */ 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) - && (beam_dir * positions[i] >= closest - || beam_dir * positions[i - 1] >= closest)) - concave = true; + && (beam_dir * positions[i] >= closest + || beam_dir * positions[i - 1] >= closest)) + concave = 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); + && (beam_dir * positions[i] > closest); } concave = concave || all_closer; @@ -62,7 +91,7 @@ calc_positions_concaveness (vector const &positions, Direction beam_dir) 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]; @@ -80,14 +109,13 @@ calc_positions_concaveness (vector const &positions, Direction beam_dir) return concaveness; } - MAKE_SCHEME_CALLBACK (Beam, calc_concaveness, 1); SCM Beam::calc_concaveness (SCM smob) { Grob *me = unsmob_grob (smob); - vector stems + vector stems = extract_grob_array (me, "stems"); if (is_knee (me)) @@ -96,29 +124,28 @@ Beam::calc_concaveness (SCM smob) Direction beam_dir = CENTER; for (vsize i = stems.size (); i--;) { - if (Stem::is_invisible (stems[i])) - stems.erase (stems.begin () + i); + if (Stem::is_normal_stem (stems[i])) + { + if (Direction dir = get_grob_direction (stems[i])) + beam_dir = dir; + } else - { - if (Direction dir = get_grob_direction (stems[i])) - beam_dir = dir; - } + stems.erase (stems.begin () + i); } if (stems.size () <= 2) - return SCM_UNSPECIFIED; + return scm_from_int (0); vector close_positions; vector far_positions; for (vsize i = 0; i < stems.size (); i++) { /* - For chords, we take the note head that is closest to 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. + For chords, we take the note head that is closest to 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]); @@ -128,18 +155,16 @@ Beam::calc_concaveness (SCM smob) 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; } else { concaveness = (calc_positions_concaveness (far_positions, beam_dir) - + calc_positions_concaveness (close_positions, beam_dir)) / 2; + + calc_positions_concaveness (close_positions, beam_dir)) / 2; } return scm_from_double (concaveness); } - -