From: Mike Solomon Date: Mon, 28 Feb 2011 01:28:28 +0000 (-0500) Subject: Comments to the beam collision engraver X-Git-Tag: release/2.13.52-1~14 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=c9f2e5f23fd435ab69b4313a2e5902556cc91511;p=lilypond.git Comments to the beam collision engraver --- diff --git a/lily/beam-collision-engraver.cc b/lily/beam-collision-engraver.cc index 67106cb8e7..39e614c2a1 100644 --- a/lily/beam-collision-engraver.cc +++ b/lily/beam-collision-engraver.cc @@ -47,12 +47,22 @@ public: void Beam_collision_engraver::stop_translation_timestep () { + /* + First, for all grobs that fall to the left of a beam during + a timestep (i.e. clefs, time signatures), add these to + the beams that are currently active. + */ for (vsize i = 0; i < covered_interior_grobs_.size (); i++) for (vsize j = 0; j < active_beams_.size (); j++) Pointer_group_interface::add_grob (active_beams_[j], ly_symbol2scm ("covered-grobs"), covered_interior_grobs_[i]); covered_interior_grobs_.clear (); + /* + If a signaled beam is already in active_beams_, we erase it so as + not to have a beam represented in active_beams_ more than once. + */ + for (vsize i = 0; i < active_beams_.size (); i++) for (vsize j = 0; j < signaled_beams_.size (); j++) if (active_beams_[i] == signaled_beams_[j]) @@ -62,9 +72,11 @@ Beam_collision_engraver::stop_translation_timestep () } /* - hack. - in auto beaming, end beams are signaled with their beams at a later timestep. - we need to scrub these. + In auto beaming, beams both begin and end during the same timestep. + This means that if there is a beam that is both in signaled_beams_ and + end_beams_, it must either be an auto beam (likely) or a beam that + has no notes under it (highly unlikely). In either case, we cannot account + for the grobs under this beam, and we erase it from signaled beams. */ for (vsize i = 0; i < end_beams_.size (); i++) for (vsize j = 0; j < signaled_beams_.size (); j++) @@ -74,11 +86,25 @@ Beam_collision_engraver::stop_translation_timestep () break; } + /* + We want to know how big active beams was originally so that we do not + get any cyclical dependencies (see below). + */ vsize orig_size = active_beams_.size (); + /* + All signaled beams that are left now become active beams that are fair + game to collect covered grobs. + */ for (vsize i=0; i < signaled_beams_.size (); i++) active_beams_.push_back (signaled_beams_[i]); + /* + Add all covered grobs that fall to the right of a beam (like noteheads) + as to covered-grobs of the beam. Note that noteheads that part of a beam + are not added to that list, as note heads should not never collide with + their own beams due to minimum stem length penalties in beam-quanting.cc. + */ for (vsize i = 0; i < covered_grobs_.size (); i++) for (vsize j = 0; j < active_beams_.size (); j++) { @@ -93,12 +119,25 @@ Beam_collision_engraver::stop_translation_timestep () covered_grobs_.clear (); + /* + This is where cyclical dependencies are avoided. In beam collision avoidance, + beams often need to avoid other beams. To do this, they need to know the beam's + position. But, if that second beam needs to know the first beam's position, we + have a cyclical dependency. So, we only ever add signaled beams to active_beams_ + that existed BEFORE this time step. This is controlled by the orig_size variable. + The for loop stops before it gets to the signaled beams added above so that beams + added during this timestep are never dependent on each other for positioning. + */ for (vsize i = 0; i < signaled_beams_.size (); i++) for (vsize j = 0; j < orig_size; j++) Pointer_group_interface::add_grob (active_beams_[j], ly_symbol2scm ("covered-grobs"), signaled_beams_[i]); signaled_beams_.clear (); + /* + If the end of a beam has been announced, it is no longer active. So, remove this beam + from active_beams_. + */ for (vsize i = 0; i < end_beams_.size (); i++) for (vsize j = 0; j < active_beams_.size (); j++) if (end_beams_[i] == active_beams_[j])