- /*
- to prevent numerical inaccuracies in
- Bezier::get_other_coordinate ().
- */
- Direction d = LEFT;
- bool found = false;
- Real y = 0.0;
-
- do
- {
- /*
- We need to check for the bound explicitly, since the
- slur-ending can be almost vertical, making the Y
- coordinate a bad approximation of the object-slur
- distance.
- */
- Item * as_item = dynamic_cast<Item*> (collision_infos[j].grob_);
- if ((as_item
- && as_item->get_column ()
- == state.extremes_[d] .bound_->get_column ())
- || collision_infos[j].extents_[X_AXIS].contains (attachment[d][X_AXIS]))
- {
- y = attachment[d][Y_AXIS];
- found = true;
- }
- }
- while (flip (&d) != LEFT);
-
- if (!found)
- {
- Real x = collision_infos[j].extents_[X_AXIS]
- .linear_combination (collision_infos[j].idx_);
-
- if (!slur_wid.contains (x))
- continue;
-
- y = state.scores_->elem (i).curve_.get_other_coordinate (X_AXIS, x);
- }
-
- Real dist = collision_infos[j].extents_[Y_AXIS].distance (y);
- demerit +=
- fabs (0 >? (state.parameters_.extra_encompass_free_distance_ - dist)) /
- state.parameters_.extra_encompass_free_distance_
- * collision_infos[j].penalty_;
- }
-#if DEBUG_SLUR_QUANTING
- (*state.scores_)[i].score_card_ += to_string ("X%.2f", demerit);
-#endif
- (*state.scores_)[i].score_ += demerit;
- }
-}
-
-void
-score_edges (Slur_score_state const &state)
-{
- for (int i = 0; i < state.scores_->size (); i++)
- {
- Direction d = LEFT;
- Slur_score &config = state.scores_->elem_ref (i);
- Offset dz = config.attachment_[RIGHT] - config.attachment_[LEFT];
- Real slope = dz[Y_AXIS] / dz[X_AXIS];
- do
- {
- Real y = config.attachment_[d][Y_AXIS];
- Real dy = fabs (y - state.base_attachments_[d][Y_AXIS]);
-
- Real factor = state.parameters_.edge_attraction_factor_;
- Real demerit = factor * dy;
- if (state.extremes_[d].stem_
- && state.extremes_[d].stem_dir_ == state.dir_
- && !Stem::get_beaming (state.extremes_[d].stem_, -d)
- )
- demerit /= 5;
-
- demerit *= exp (state.dir_ * d * slope
- * state.parameters_.edge_slope_exponent_ );
-
- (*state.scores_)[i].score_ += demerit;
-#if DEBUG_SLUR_QUANTING
- (*state.scores_)[i].score_card_ += to_string ("E%.2f", demerit);
-#endif
- }
- while (flip (&d) != LEFT);
- }
-}
-
-void
-score_slopes (Slur_score_state const &state)
-{
-
- Drul_array<Real> ys;
- Direction d = LEFT;
- do
- {
- if (state.extremes_[d].slur_head_)
- ys[d] = state.extremes_[d].slur_head_->relative_coordinate (state.common_[Y_AXIS],
- Y_AXIS);
- else
- ys[d] = state.extremes_[d].neighbor_y_;
- }
- while (flip (&d) != LEFT);
-
- bool has_beams
- = (state.extremes_[LEFT].stem_ && Stem::get_beam (state.extremes_[LEFT].stem_))
- || (state.extremes_[RIGHT].stem_ && Stem::get_beam (state.extremes_[RIGHT].stem_));
-
- Real dy = ys[RIGHT] - ys[LEFT];
- for (int i = 0; i < state.scores_->size (); i++)
- {
- Offset slur_dz = (*state.scores_)[i].attachment_[RIGHT]
- - (*state.scores_)[i].attachment_[LEFT];
- Real slur_dy = slur_dz[Y_AXIS];
- Real demerit = 0.0;
-
- demerit += ((fabs (slur_dy / slur_dz[X_AXIS])
- - state.parameters_.max_slope_) >? 0)
- * state.parameters_.max_slope_factor_;
-
- /* 0.2: account for staffline offset. */
- Real max_dy = (fabs (dy) + 0.2);
- if (has_beams)
- max_dy += 1.0;
-
- demerit += state.parameters_.steeper_slope_factor_
- * ((fabs (slur_dy) -max_dy) >? 0);
-
- demerit += ((fabs (slur_dy/slur_dz[X_AXIS])
- - state.parameters_.max_slope_) >? 0)
- * state.parameters_.max_slope_factor_;
-
- if (sign (dy) == 0
- && sign (slur_dy) != 0)
- demerit += state.parameters_.non_horizontal_penalty_;
-
- if (sign (dy)
- && sign (slur_dy)
- && sign (slur_dy) != sign (dy))
- demerit += has_beams
- ? state.parameters_.same_slope_penalty_ / 10
- : state.parameters_.same_slope_penalty_;
-
-#if DEBUG_SLUR_QUANTING
- (*state.scores_)[i].score_card_ += to_string ("S%.2f", d);
-#endif
- (*state.scores_)[i].score_ += demerit;
- }
-
-
-
-}
-
-
-Real
-fit_factor (Offset dz_unit, Offset dz_perp,
- Bezier curve, Direction d, Array<Offset> const &avoid)
-{
- Real fit_factor = 0.0;
- Offset x0 = curve.control_[0];
- curve.translate (-x0);
- curve.rotate (-dz_unit.arg ());
- curve.scale (1, d);
-
- Interval curve_xext;
- curve_xext.add_point (curve.control_[0][X_AXIS]);
- curve_xext.add_point (curve.control_[3][X_AXIS]);
-
- for (int i = 0; i < avoid.size (); i++)
- {
- Offset z = (avoid[i] - x0) ;
- Offset p (dot_product (z, dz_unit),
- d* dot_product (z, dz_perp));
- if (!curve_xext.contains (p[X_AXIS]))
- continue;
-
- Real y = curve.get_other_coordinate (X_AXIS, p[X_AXIS]);
- if (y)
- {
- fit_factor = fit_factor >? (p[Y_AXIS] / y);
- }
- }
- return fit_factor;