lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

First pass at avoiding very high slurs (fixes issue 163). (issue4817048)


From: mtsolo
Subject: First pass at avoiding very high slurs (fixes issue 163). (issue4817048)
Date: Sat, 23 Jul 2011 20:50:47 +0000

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)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]