Index: lily/beam-quanting.cc |
diff --git a/lily/beam-quanting.cc b/lily/beam-quanting.cc |
index 43c8f393b287463b6bf964d3a68c271af2b4a202..51244125a66632833d211a466047037a92cee5a1 100644 |
--- a/lily/beam-quanting.cc |
+++ b/lily/beam-quanting.cc |
@@ -50,10 +50,13 @@ Beam_quant_parameters::fill (Grob *him) |
{ |
SCM details = him->get_property ("details"); |
+ PRESSURE = robust_scm2interval (him->get_property ("collision-bounds"), Interval (Beam::no_pressure, Beam::no_pressure)); |
SECONDARY_BEAM_DEMERIT = get_detail (details, ly_symbol2scm ("secondary-beam-demerit"), 10.0); |
STEM_LENGTH_DEMERIT_FACTOR = get_detail (details, ly_symbol2scm ("stem-length-demerit-factor"), 5); |
REGION_SIZE = get_detail (details, ly_symbol2scm ("region-size"), 2); |
BEAM_EPS = get_detail (details, ly_symbol2scm ("beam-eps"), 1e-3); |
+ PREEMPTIVE_COLLISION_PENALTY = get_detail (details, ly_symbol2scm ("preemptive-collision-penalty"), 500); |
+ HARD_COLLISION_PENALTY = get_detail (details, ly_symbol2scm ("hard-collision-penalty"), 10000); |
STEM_LENGTH_LIMIT_PENALTY = get_detail (details, ly_symbol2scm ("stem-length-limit-penalty"), 5000); |
DAMPING_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("damping-direction-penalty"), 800); |
HINT_DIRECTION_PENALTY = get_detail (details, ly_symbol2scm ("hint-direction-penalty"), 20); |
@@ -304,7 +307,10 @@ void Beam_scoring_problem::one_scorer (Beam_configuration* config) const |
case STEM_LENGTHS: |
score_stem_lengths (config); |
break; |
- |
+ case COLLIDING: |
+ score_colliding_quants (config); |
+ break; |
+ |
case NUM_SCORERS: |
case ORIGINAL_DISTANCE: |
default: |
@@ -596,3 +602,35 @@ Beam_scoring_problem::score_forbidden_quants (Beam_configuration *config) const |
config->add (dem, "F"); |
} |
+void |
+Beam_scoring_problem::score_colliding_quants (Beam_configuration *config) const |
+{ |
+ |
+ /* Aim to attain a result as close to the original quanting as possible */ |
+ bool cond = false; |
+ Direction dir = UP; |
+ do |
+ { |
+ cond = cond || ((unquanted_y[LEFT] + (parameters.PRESSURE[dir] * dir)) * dir > config->y[LEFT] * dir) |
+ || ((unquanted_y[RIGHT] + (parameters.PRESSURE[dir] * dir)) * dir > config->y[RIGHT] * dir); |
+ } |
+ while (flip (&dir) != UP); |
+ |
+ Real dem = 0.0; |
+ if (cond) |
+ dem += parameters.HARD_COLLISION_PENALTY; |
+ else if (!(parameters.PRESSURE[UP] <= 0.0) || !(parameters.PRESSURE[DOWN] <= 0.0)) |
+ { |
+ dir = UP; |
+ do |
+ { |
+ /* Prevents beams from going too far in the direction opposite a collision. */ |
+ dem += fabs (parameters.PRESSURE[dir]) > Beam::no_pressure ? |
+ pow (fabs (config->y[LEFT] - (unquanted_y[LEFT] + (parameters.PRESSURE[dir] * dir))) |
+ + fabs (config->y[RIGHT] - (unquanted_y[RIGHT] + (parameters.PRESSURE[dir] * dir))), 2) * parameters.PREEMPTIVE_COLLISION_PENALTY : 0.0; |
+ } |
+ while (flip (&dir) != UP); |
+ dem = sqrt (dem); |
+ } |
+ config->add (dem, "C"); |
+} |