- /*
- Can't we simply compute the distance between the nearest
- staffline and the secondary beam? That would get rid of the
- silly case analysis here (which is probably not when we have
- different beam-thicknesses.)
-
- --hwn
- */
-
-
- // hmm, without Interval/Drul_array, you get ~ 4x same code...
- if (fabs (yl - ldir * beam_translation) < rad + inter)
- {
- if (ldir == UP && dy <= eps
- && fabs (my_modf (yl) - sit) < eps)
- dem += SECONDARY_BEAM_DEMERIT;
-
- if (ldir == DOWN && dy >= eps
- && fabs (my_modf (yl) - hang) < eps)
- dem += SECONDARY_BEAM_DEMERIT;
- }
-
- if (fabs (yr - rdir * beam_translation) < rad + inter)
- {
- if (rdir == UP && dy >= eps
- && fabs (my_modf (yr) - sit) < eps)
- dem += SECONDARY_BEAM_DEMERIT;
-
- if (rdir == DOWN && dy <= eps
- && fabs (my_modf (yr) - hang) < eps)
- dem += SECONDARY_BEAM_DEMERIT;
- }
-
- if (beam_count >= 3)
- {
- if (fabs (yl - 2 * ldir * beam_translation) < rad + inter)
- {
- if (ldir == UP && dy <= eps
- && fabs (my_modf (yl) - straddle) < eps)
- dem += SECONDARY_BEAM_DEMERIT;
-
- if (ldir == DOWN && dy >= eps
- && fabs (my_modf (yl) - straddle) < eps)
- dem += SECONDARY_BEAM_DEMERIT;
- }
-
- if (fabs (yr - 2 * rdir * beam_translation) < rad + inter)
- {
- if (rdir == UP && dy >= eps
- && fabs (my_modf (yr) - straddle) < eps)
- dem += SECONDARY_BEAM_DEMERIT;
-
- if (rdir == DOWN && dy <= eps
- && fabs (my_modf (yr) - straddle) < eps)
- dem += SECONDARY_BEAM_DEMERIT;
- }
- }
+void
+Beam_scoring_problem::score_collisions (Beam_configuration *config) const
+{
+ Real demerits = 0.0;
+ for (vsize i = 0; i < collisions_.size (); i++)
+ {
+ Interval collision_y = collisions_[i].y_;
+ Real x = collisions_[i].x_;
+
+ Real center_beam_y = y_at (x, config);
+ Interval beam_y = center_beam_y + collisions_[i].beam_y_;
+
+ Real dist = infinity_f;
+ if (!intersection (beam_y, collision_y).is_empty ())
+ dist = 0.0;
+ else
+ dist = min (beam_y.distance (collision_y[DOWN]),
+ beam_y.distance (collision_y[UP]));
+
+ Real scale_free
+ = max (parameters.COLLISION_PADDING - dist, 0.0) /
+ parameters.COLLISION_PADDING;
+ demerits
+ += collisions_[i].base_penalty_ *
+ pow (scale_free, 3) * parameters.COLLISION_PENALTY;