From 4bae96d93d05b96bbf79b722155b2b5795418278 Mon Sep 17 00:00:00 2001 From: Keith OHara Date: Tue, 13 Mar 2012 23:29:13 -0700 Subject: [PATCH] note-collision.cc: distinguish suspended notes; issue 984. --- input/regression/collision-seconds.ly | 18 ++++++--- lily/include/stem.hh | 2 +- lily/note-collision.cc | 58 ++++++++++++++------------- lily/stem.cc | 11 +++-- 4 files changed, 51 insertions(+), 38 deletions(-) diff --git a/input/regression/collision-seconds.ly b/input/regression/collision-seconds.ly index 70b0e052e0..ea9a727355 100644 --- a/input/regression/collision-seconds.ly +++ b/input/regression/collision-seconds.ly @@ -1,10 +1,16 @@ -\version "2.14.0" +\version "2.13.34" \header { - texidoc = "Seconds do not confuse the collision algorithm too much. The best -way to format this would be to merge the two Ds, but we will be happy for now -if the upstem D does not collide with the downstem C." + texidoc = "Seconds do not confuse the collision algorithm. +The first pair of chords in each measure should merge, mesh, +or come relatively close, but the second in each measure needs +more space to make clear which notes belong to which voice." } - -<< d' \\ >> +\relative f << { + 2 + \bar "||" +} \\ { + + +} >> diff --git a/lily/include/stem.hh b/lily/include/stem.hh index b1c1324ea8..de1b7d6c9a 100644 --- a/lily/include/stem.hh +++ b/lily/include/stem.hh @@ -28,7 +28,7 @@ class Stem { public: - static vector note_head_positions (Grob *); + static vector note_head_positions (Grob *, bool filter = false); static int duration_log (Grob *); static void set_beaming (Grob *, int, Direction d); static int get_beaming (Grob *, Direction d); diff --git a/lily/note-collision.cc b/lily/note-collision.cc index 3d14a3649b..6a2abb6714 100644 --- a/lily/note-collision.cc +++ b/lily/note-collision.cc @@ -56,13 +56,35 @@ check_meshing_chords (Grob *me, Grob *head_up = Note_column::first_head (clash_up); Grob *head_down = Note_column::first_head (clash_down); - vector ups = Stem::note_head_positions (Note_column::get_stem (clash_up)); - vector dps = Stem::note_head_positions (Note_column::get_stem (clash_down)); + /* Staff-positions of all noteheads on each stem */ + vector ups = Stem::note_head_positions (stems[UP]); + vector dps = Stem::note_head_positions (stems[DOWN]); /* Too far apart to collide. */ if (ups[0] > dps.back () + 1) return; + /* If the chords just 'touch' their extreme noteheads, + then we can align their stems. + */ + bool touch = false; + if (ups[0] >= dps.back () + && (dps.size () < 2 || ups[0] >= dps[dps.size () - 2] + 2) + && (ups.size () < 2 || ups[1] >= dps.back () + 2)) + touch = true; + + /* Filter out the 'o's in this configuration, since they're no + * part in the collision. + * + * | + * x|o + * x|o + * x + * + */ + ups = Stem::note_head_positions (stems[UP], true); + dps = Stem::note_head_positions (stems[DOWN], true); + /* Merge heads if the notes lie the same line, or if the "stem-up-note" is above the "stem-down-note". */ bool merge_possible = (ups[0] >= dps[0]) && (ups.back () >= dps.back ()); @@ -118,16 +140,6 @@ check_meshing_chords (Grob *me, * */ - /* TODO: filter out the 'o's in this configuration, since they're no - * part in the collision. - * - * | - * x|o - * x|o - * x - * - */ - bool close_half_collide = false; bool distant_half_collide = false; bool full_collide = false; @@ -163,16 +175,6 @@ check_meshing_chords (Grob *me, full_collide = full_collide || (close_half_collide && distant_half_collide); - /* If the only collision is in the extreme noteheads, - then their stems can line up and the chords just 'touch'. - A half collision with the next note along the chord prevents touching. - */ - bool touch = false; - if (ups[0] >= dps.back () - && (dps.size () < 2 || ups[0] >= dps[dps.size () - 2] + 2) - && (ups.size () < 2 || ups[1] >= dps.back () + 2)) - touch = true; - /* Determine which chord goes on the left, and which goes right. Up-stem usually goes on the right, but if chords just 'touch' we can put both stems on a common vertical line. In the presense of collisions, @@ -525,12 +527,12 @@ Note_collision_interface::automatic_shift (Grob *me, while ((flip (&d)) != UP); /* - do horizontal shifts of each direction - - | - x|| - x|| - x| + * do horizontal shifts of each direction + * + * | + * x|| + * x|| + * x| */ do diff --git a/lily/stem.cc b/lily/stem.cc index 8c0e128487..f662f3cf1d 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -236,18 +236,23 @@ Stem::extremal_heads (Grob *me) return exthead; } -/* The positions, in ascending order. */ +/* The staff positions, in ascending order. + * If FILTER, include the main column of noteheads only */ vector -Stem::note_head_positions (Grob *me) +Stem::note_head_positions (Grob *me, bool filter) { vector ps; extract_grob_set (me, "note-heads", heads); + Grob *xref = common_refpoint_of_array (heads, me, X_AXIS); for (vsize i = heads.size (); i--;) { Grob *n = heads[i]; - int p = Staff_symbol_referencer::get_rounded_position (n); + if (filter + && n->relative_coordinate (xref, X_AXIS) != 0.0) + continue; + int p = Staff_symbol_referencer::get_rounded_position (n); ps.push_back (p); } -- 2.39.2