- Real shift = min (max ( (Stem::head_positions (left)[beamdir]
- + Stem::head_positions (right)[beamdir]) / 2.0,
- rest_max_pos[DOWN]),
- rest_max_pos[UP]
- ) * ss / 2.0
- - previous;
- /* Always move by a whole number of staff spaces */
- shift = ceil (fabs (shift / ss)) * ss * sign (shift);
-
- return scm_from_double (previous + shift);
+ Real beam_pos = (Stem::head_positions (left)[beamdir]
+ + Stem::head_positions (right)[beamdir]) / 2.0
+ + 4.0 * beamdir; // four staff-positions
+ /* and that the closest beam never crosses staff center by more than two positions */
+ beam_pos = max (-2.0, beam_pos * beamdir) * beamdir;
+
+ Real minimum_distance
+ = ss * (robust_scm2double (stem->get_property ("stemlet-length"), 0.0)
+ + robust_scm2double (me->get_property ("minimum-distance"), 0.0));
+ Real offset = beam_pos * ss / 2.0
+ - minimum_distance * beamdir
+ - me->extent (me, Y_AXIS)[beamdir];
+ Real previous = robust_scm2double (prev_offset, 0.0);
+
+ /* Always move by a whole number of staff spaces, always away from the beam */
+ offset = floor (min (0.0, (offset - previous) / ss * beamdir))
+ * ss * beamdir + previous;
+
+ return scm_from_double (offset);