X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fbeam-concave.cc;h=4eb2bab8fd3b56f3286fedee71f404253e4536d5;hb=d445cda01e4d86896f55fd1cf2ccbaba8cb7917a;hp=07d0e3b335a2d7c300dc9b76a2ac098dad8db472;hpb=1f8e2327f25d602dd8bf308150136a3cb2424d33;p=lilypond.git diff --git a/lily/beam-concave.cc b/lily/beam-concave.cc index 07d0e3b335..4eb2bab8fd 100644 --- a/lily/beam-concave.cc +++ b/lily/beam-concave.cc @@ -1,16 +1,13 @@ /* - Determine whether a beam is concave. - */ -#include + Determine whether a beam is concave. +*/ - -#include "group-interface.hh" +#include "pointer-group-interface.hh" #include "array.hh" -#include "grob.hh" #include "stem.hh" -#include "interval.hh" #include "beam.hh" #include "staff-symbol-referencer.hh" +#include "directional-element-interface.hh" bool is_concave_single_notes (Array const &positions, Direction beam_dir) @@ -22,38 +19,37 @@ is_concave_single_notes (Array const &positions, Direction beam_dir) bool above = false; bool below = false; bool concave = false; - + /* notes above and below the interval covered by 1st and last note. - */ + */ for (int i = 1; i < positions.size () - 1; i++) { above = above || (positions[i] > covering[UP]); below = below || (positions[i] < covering[DOWN]); } - concave = concave || (above && below); /* 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 = (beam_dir * positions.top()) >? (beam_dir *positions[0]); + */ + 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 inner_dy = positions[i] - positions[i-1]; + 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)) + || beam_dir * positions[i - 1] >= closest)) concave = true; } - - bool all_closer = true; - for (int i = 1; all_closer && i < positions.size ()-1; i++) + + bool all_closer = true; + for (int i = 1; all_closer && i < positions.size () - 1; i++) { - all_closer = all_closer && - (beam_dir * positions[i] > closest); + all_closer = all_closer + && (beam_dir * positions[i] > closest); } concave = concave || all_closer; @@ -61,19 +57,19 @@ is_concave_single_notes (Array const &positions, Direction beam_dir) } Real -calc_concaveness (Array const &positions, Direction beam_dir) +calc_positions_concaveness (Array const &positions, Direction beam_dir) { Real dy = positions.top () - positions[0]; - Real slope = dy / Real (positions.size() - 1); + Real slope = dy / Real (positions.size () - 1); Real concaveness = 0.0; - for (int i = 1; i < positions.size() - 1; i++) + for (int i = 1; i < positions.size () - 1; i++) { Real line_y = slope * i + positions[0]; - concaveness += (beam_dir * (positions[i] - line_y)) >? 0.0; + concaveness += max (beam_dir * (positions[i] - line_y), 0.0); } - concaveness /= positions.size () ; + concaveness /= positions.size (); /* Normalize. For dy = 0, the slope ends up as 0 anyway, so the @@ -84,37 +80,37 @@ calc_concaveness (Array const &positions, Direction beam_dir) return concaveness; } -MAKE_SCHEME_CALLBACK (Beam, check_concave, 1); + +MAKE_SCHEME_CALLBACK (Beam, calc_concaveness, 1); SCM -Beam::check_concave (SCM smob) +Beam::calc_concaveness (SCM smob) { Grob *me = unsmob_grob (smob); - Link_array stems = - Pointer_group_interface__extract_grobs (me, (Grob*) 0, "stems"); + Link_array stems + = extract_grob_array (me, "stems"); if (is_knee (me)) - return SCM_UNSPECIFIED; - + return scm_from_double (0.0); + Direction beam_dir = CENTER; - for (int i = stems.size (); i--; ) + for (int i = stems.size (); i--;) { if (Stem::is_invisible (stems[i])) stems.del (i); else { - if (Direction dir = Stem::get_direction (stems[i])) + if (Direction dir = get_grob_direction (stems[i])) beam_dir = dir; } } - + if (stems.size () <= 2) return SCM_UNSPECIFIED; - Array close_positions; Array far_positions; - for (int i= 0; i < stems.size (); i++) + for (int i = 0; i < stems.size (); i++) { /* For chords, we take the note head that is closest to the beam. @@ -122,31 +118,28 @@ 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. - - */ + + */ Interval posns = Stem::head_positions (stems[i]); - + close_positions.push ((int) rint (posns[beam_dir])); far_positions.push ((int) rint (posns[-beam_dir])); } - if (is_concave_single_notes (far_positions, beam_dir)) - { - Drul_array 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 (r, r))); - me->set_property ("least-squares-dy", scm_make_real (0)); + if (is_concave_single_notes (far_positions, beam_dir)) + { + concaveness = 10000; } 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); } + + +