- /*
- Take the position between the two bounding head_positions,
- then bound it by the minimum and maximum positions outside the staff.
- 4.0 = 2.0 to get out of staff space * 2.0 for the average
- */
- amount = min (max ((Stem::head_positions (left)[beamdir] + Stem::head_positions (right)[beamdir]) / 4.0, rest_max_pos[DOWN]), rest_max_pos[UP]);
+ 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];
+
+ /* 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;