- (void) me;
- (void) base_attach;
-
- Drul_array<Real> ys;
- Direction d = LEFT;
- do
- {
- if (extremes[d].slur_head_)
- ys[d] = extremes[d].slur_head_->relative_coordinate (common[Y_AXIS],
- Y_AXIS);
- else
- ys[d] = extremes[d].neighbor_y_;
- }
- while (flip (&d) != LEFT);
-
- bool has_beams
- = (extremes[LEFT].stem_ && Stem::get_beam (extremes[LEFT].stem_))
- || (extremes[RIGHT].stem_ && Stem::get_beam (extremes[RIGHT].stem_));
-
- Real dy = ys[RIGHT] - ys[LEFT];
- for (int i = 0; i < scores->size (); i++)
- {
- Offset slur_dz = (*scores)[i].attachment_[RIGHT]
- - (*scores)[i].attachment_[LEFT];
- Real slur_dy = slur_dz[Y_AXIS];
- Real demerit = 0.0;
-
- demerit += ((fabs (slur_dy / slur_dz[X_AXIS])
- - score_param->max_slope_) >? 0)
- * score_param->max_slope_factor_;
-
- /* 0.2: account for staffline offset. */
- Real max_dy = (fabs (dy) + 0.2);
- if (has_beams)
- max_dy += 1.0;
-
- demerit += score_param->steeper_slope_factor_
- * ((fabs (slur_dy) -max_dy) >? 0);
-
- demerit += ((fabs (slur_dy/slur_dz[X_AXIS])
- - score_param->max_slope_) >? 0)
- * score_param->max_slope_factor_;
-
- if (sign (dy) == 0
- && sign (slur_dy) != 0)
- demerit += score_param->non_horizontal_penalty_;
-
- if (sign (dy)
- && sign (slur_dy)
- && sign (slur_dy) != sign (dy))
- demerit += has_beams
- ? score_param->same_slope_penalty_ / 10
- : score_param->same_slope_penalty_;
-
-#if DEBUG_SLUR_QUANTING
- (*scores)[i].score_card_ += to_string ("S%.2f", d);
-#endif
- (*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;
-}
-
-
-Bezier
-get_bezier (Grob *me,
- Grob **common,
- Slur_score_parameters *score_param,
- Drul_array<Bound_info> extremes,
- Drul_array<Offset> attachments,
- Real r_0, Real h_inf
- )
-{
- Link_array<Grob> encompasses
- = Pointer_group_interface__extract_grobs (me, (Grob *)0, "note-columns");
- Direction dir = get_grob_direction (me);
-
- Array<Offset> avoid;
- for (int i = 0; i < encompasses.size(); i++)
- {
- if (extremes[LEFT].note_column_ == encompasses[i]
- ||extremes[RIGHT].note_column_ == encompasses[i])
- continue;
-
- Encompass_info inf (get_encompass_info (me, encompasses[i], common));
-
- Real y = dir*((dir * inf.head_) >? (dir *inf.stem_));
-
- avoid.push (Offset (inf.x_, y + dir * score_param->free_head_distance_));
- }
-
- Link_array<Grob> extra_encompasses
- = Pointer_group_interface__extract_grobs (me, (Grob *)0, "encompass-objects");
- for (int i = 0; i < extra_encompasses.size (); i++)
- if (Slur::has_interface (extra_encompasses[i]))
- {
- Grob * small_slur = extra_encompasses[i];
- Bezier b = Slur::get_curve (small_slur);
-
- Offset z = b.curve_point (0.5);
- z += Offset (small_slur->relative_coordinate (common[X_AXIS], X_AXIS),
- small_slur->relative_coordinate (common[Y_AXIS], Y_AXIS));
-
- z[Y_AXIS] += dir * score_param->free_slur_distance_;
- avoid.push (z);
- }
-
- Offset dz = attachments[RIGHT]- attachments[LEFT];;
- Offset dz_unit = dz;
- dz_unit *= 1 / dz.length();
- Offset dz_perp = dz_unit * Offset(0,1);
-
- Real indent, height;
- get_slur_indent_height (&indent, &height, dz.length (), h_inf, r_0);
-
- Real excentricity = robust_scm2double (me->get_property ("excentricity"), 0.0);
- Bezier curve;
-
- Real x1 = (excentricity + indent);
- Real x2 = (excentricity - indent);
- curve.control_[0] = attachments[LEFT];
- curve.control_[1] = attachments[LEFT] + dz_perp * height * dir + dz_unit * x1;
- curve.control_[2] = attachments[RIGHT] + dz_perp * height * dir + dz_unit * x2;
- curve.control_[3] = attachments[RIGHT];
-
-
- Real ff = fit_factor (dz_unit, dz_perp, curve, dir, avoid);
- Real l = dz.length ();
-
- /*
- This condition,
-
- l^2 > 4h^2 + 3(i 1/3l)^2 - 1/3 l^2
-
- is equivalent to:
-
- |bez'(0)| < | bez'(.5)|
-
- when (control2-control1) has the same direction as (control3 -
- control0).
-
- */
- Real max_h = sqrt (sqr (l)/3 - .75 * sqr (indent + l / 3));
- height = height >? ((height * ff) <? max_h);
-
- curve.control_[0] = attachments[LEFT];
- curve.control_[1] = attachments[LEFT] + dz_perp * height * dir + dz_unit * x1;
- curve.control_[2] = attachments[RIGHT] + dz_perp * height * dir + dz_unit * x2;
- curve.control_[3] = attachments[RIGHT];
-
- return curve;