Reviewers: ,
Message:
Hey all,
This fixes issue 163. The only downside is that it adds another entry
to an already-crowded details list. I also use a magic number of 2
(you'll see a comment about it) that should likely itself either be a
details entry or be taken from an existing details entry.
I agree with Han-Wen's comment in the source that there are too many
properties and that it risks to become unwieldy, so although I like this
patch because it makes a few of my scores look better, I'd like to have
a discussion about consolidating and/or better documenting the details
list in conjunction with the pushing of this patch. Ideally, I'd like
to see a regtest that clearly demonstrates the utility (and
indispensability) of each entry in the details list. By constructing
these regtests, it'll likely make pruning the list easier.
Cheers,
MS
Description:
First pass at avoiding very high slurs (fixes issue 163).
Please review this at http://codereview.appspot.com/4817048/
Affected files:
M lily/include/slur-score-parameters.hh
M lily/slur-configuration.cc
M lily/slur-score-parameters.cc
M lily/slur.cc
M scm/layout-slur.scm
Index: lily/include/slur-score-parameters.hh
diff --git a/lily/include/slur-score-parameters.hh
b/lily/include/slur-score-parameters.hh
index
49d159b9390da0a2aebb9589e62d1947b1ea1bd2..d714496d69b14eb5f8f6c1741bac30924c840740
100644
--- a/lily/include/slur-score-parameters.hh
+++ b/lily/include/slur-score-parameters.hh
@@ -27,7 +27,9 @@ struct Slur_score_parameters
int region_size_;
Real head_encompass_penalty_;
+ Real max_distance_from_head_penalty;
Real stem_encompass_penalty_;
+ Real max_distance_from_head_penalty_;
Real closeness_factor_;
Real edge_attraction_factor_;
Real same_slope_penalty_;
Index: lily/slur-configuration.cc
diff --git a/lily/slur-configuration.cc b/lily/slur-configuration.cc
index
e83856364db6dbb3a4f2e111915d5a55f44fafdf..934515df1850b01946ce15b2b6cbfd1306aa2543
100644
--- a/lily/slur-configuration.cc
+++ b/lily/slur-configuration.cc
@@ -210,6 +210,8 @@ Slur_configuration::score_encompass (Slur_score_state
const &state)
attachment points.
*/
vector<Real> convex_head_distances;
+ Real distance_penalty = 0.0;
+ Real highest_point = -infinity_f;
for (vsize j = 0; j < state.encompass_infos_.size (); j++)
{
Real x = state.encompass_infos_[j].x_;
@@ -237,7 +239,19 @@ Slur_configuration::score_encompass (Slur_score_state
const &state)
? (1 / fabs (head_dy) - 1 /
state.parameters_.free_head_distance_)
: state.parameters_.head_encompass_penalty_;
hd = min (max (hd, 0.0),
state.parameters_.head_encompass_penalty_);
-
+ Real encompass_refpoint = minmax (state.dir_,
state.encompass_infos_[j].head_, state.encompass_infos_[j].stem_);
+ Real encompass_dy = fabs (y - encompass_refpoint);
+
+ if (fabs (encompass_refpoint) > highest_point)
+ {
+ /*
+ * 2 is the max distance allowable from the highest notehead
before
+ * we want to bring the stem down. make user settable? is
there another
+ * parameter that means more or less this?
+ */
+ distance_penalty = encompass_dy < 2 ? 0.0 : max(encompass_dy *
state.parameters_.max_distance_from_head_penalty_, distance_penalty);
+ highest_point = encompass_refpoint;
+ }
demerit += hd;
}
@@ -280,7 +294,8 @@ Slur_configuration::score_encompass (Slur_score_state
const &state)
/ state.encompass_infos_.size ();
}
}
- add_score (demerit, "encompass");
+
+ add_score (demerit + distance_penalty, "encompass");
if (convex_head_distances.size ())
{
@@ -408,7 +423,41 @@ Slur_configuration::score_edges (Slur_score_state
const &state)
Real dy = fabs (y - state.base_attachments_[d][Y_AXIS]);
Real factor = state.parameters_.edge_attraction_factor_;
- Real demerit = factor * dy;
+ Real y_slope = 1.0;
+ /* we use the inverse of y-slope to lower attraction factors of stems
+ * that have large jumps between the extremals and the
next-to-extremals.
+ * this needs to be distinct from the parameter controling slope at
+ * the edges (edge_slope_exponent_). In the scenario
+ *
+ * x
+ * | x
+ * | |
+ * | |
+ * | | x
+ * | | | x
+ * | | | |
+ *
+ * it is ok for the edge slope to be extreme. But not in:
+ * x
+ * | x
+ * | | x
+ * | | |
+ * | | |
+ * | | | x
+ * | | | |
+ * This makes sense given the idea of "attraction factor" - the
edge's attraction factor
+ * is the attractiveness of the edge offset by the forces (large Y
spans between the edge
+ * and the next column) pushing a stem away from its edge.
+ */
+ if ((state.extremes_[d].note_column_ == (d == LEFT ?
state.columns_[0] : state.columns_.back ())) &&
(state.encompass_infos_.size () > 2))
+ {
+ Encompass_info ei = state.encompass_infos_[d == LEFT ? 1 :
state.encompass_infos_.size () - 2];
+ Offset encompass_dz = attachment_[d] - Offset(ei.x_, minmax
(slope > 0 ? UP : DOWN, ei.head_, ei.stem_));
+ Real slope_encompass = encompass_dz[Y_AXIS] /
encompass_dz[X_AXIS];
+ y_slope = d * (slope * slope_encompass) > 0 ? y_slope : fabs
(slope_encompass);
+ //printf ("%4.4f %4.4f %d %4.4f\n", slope, slope_encompass, d,
y_slope);
+ }
+ Real demerit = factor * dy * y_slope; // make the demerit higher if
there is a large y_slope (see above)
if (state.extremes_[d].stem_
&& state.extremes_[d].stem_dir_ == state.dir_
// TODO - Stem::get_beaming() should be precomputed.
@@ -421,7 +470,7 @@ Slur_configuration::score_edges (Slur_score_state const
&state)
string dir_str = d == LEFT ? "L" : "R";
add_score (demerit, dir_str + " edge");
- }
+ }
while (flip (&d) != LEFT);
}
Index: lily/slur-score-parameters.cc
diff --git a/lily/slur-score-parameters.cc b/lily/slur-score-parameters.cc
index
1683aeea2feace61a84496e7247cecb57fd81e6d..ee407579f1ede64bf24dfa0ee8e177638e0c4846
100644
--- a/lily/slur-score-parameters.cc
+++ b/lily/slur-score-parameters.cc
@@ -42,6 +42,8 @@ Slur_score_parameters::fill (Grob *me)
= (int) get_detail (details, ly_symbol2scm ("region-size"));
head_encompass_penalty_
= get_detail (details, ly_symbol2scm ("head-encompass-penalty"));
+ max_distance_from_head_penalty_
+ = get_detail (details, ly_symbol2scm
("max-distance-from-head-penalty"));
stem_encompass_penalty_
= get_detail (details, ly_symbol2scm ("stem-encompass-penalty"));
closeness_factor_
Index: lily/slur.cc
diff --git a/lily/slur.cc b/lily/slur.cc
index
433406c92a57d9471daab3524cf5c32091af7ebe..c8015a4d107f10776a7b50d4a7b23533f5ef3426
100644
--- a/lily/slur.cc
+++ b/lily/slur.cc
@@ -425,6 +425,8 @@ ADD_INTERFACE (Slur,
" potential endpoints in the Y direction.\n"
"@item head-encompass-penalty\n"
"Demerit to apply when note heads collide with a slur.\n"
+ "@item max-distance-from-head-penalty\n"
+ "Set this higher to force slur to be snug with noteheads.\n"
"@item stem-encompass-penalty\n"
"Demerit to apply when stems collide with a slur.\n"
"@item closeness-factor\n"
Index: scm/layout-slur.scm
diff --git a/scm/layout-slur.scm b/scm/layout-slur.scm
index
8626e0114690e832872b4aaff9cf23ce797a5e30..8487f1a35abd19c9ef96a5a06351c6c938bd0e7c
100644
--- a/scm/layout-slur.scm
+++ b/scm/layout-slur.scm
@@ -19,6 +19,7 @@
(define default-slur-details
'((region-size . 4)
(head-encompass-penalty . 1000.0)
+ (max-distance-from-head-penalty . 6.0)
(stem-encompass-penalty . 30.0)
(closeness-factor . 10)
(edge-attraction-factor . 4)
_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-devel