/*
Determine whether a beam is concave.
*/
-#include <math.h>
+#include <math.h>
#include "group-interface.hh"
#include "array.hh"
-#include "grob.hh"
#include "stem.hh"
-#include "interval.hh"
#include "beam.hh"
#include "staff-symbol-referencer.hh"
bool
-is_concave_single_notes (Array<int> positions, Direction beam_dir)
+is_concave_single_notes (Array<int> const &positions, Direction beam_dir)
{
Interval covering;
covering.add_point (positions[0]);
return concave;
}
+Real
+calc_concaveness (Array<int> const &positions, Direction beam_dir)
+{
+ Real dy = positions.top () - positions[0];
+ Real slope = dy / Real (positions.size() - 1);
+ Real concaveness = 0.0;
+ for (int i = 1; i < positions.size() - 1; i++)
+ {
+ Real line_y = slope * i + positions[0];
+
+ concaveness += (beam_dir * (positions[i] - line_y)) >? 0.0;
+ }
+
+ concaveness /= positions.size () ;
+
+ /*
+ Normalize. For dy = 0, the slope ends up as 0 anyway, so the
+ scaling of concaveness doesn't matter much.
+ */
+ if (dy)
+ concaveness /= fabs (dy);
+ return concaveness;
+}
MAKE_SCHEME_CALLBACK (Beam, check_concave, 1);
SCM
return SCM_UNSPECIFIED;
- Array<int> positions;
- for (int i= 0; i < stems.size (); i++)
+ Array<int> close_positions;
+ Array<int> far_positions;
+ for (int i = 0; i < stems.size (); i++)
{
/*
For chords, we take the note head that is closest to the beam.
the beam.
*/
- Real pos = Stem::head_positions (stems[i])[-beam_dir];
+ Interval posns = Stem::head_positions (stems[i]);
- positions.push ((int) rint (pos));
+ close_positions.push ((int) rint (posns[beam_dir]));
+ far_positions.push ((int) rint (posns[-beam_dir]));
}
- if (is_concave_single_notes (positions, beam_dir))
+ if (is_concave_single_notes (far_positions, beam_dir))
{
Drul_array<Real> pos = ly_scm2interval (me->get_property ("positions"));
Real r = linear_combination (pos, 0.0);
}
else
{
- Real dy = positions.top () - positions[0];
- Real slope = dy / Real (positions.size() - 1);
- Real concaveness = 0.0;
- for (int i = 1; i < positions.size() - 1; i++)
- {
- Real line_y = slope * i + positions[0];
-
- concaveness += (beam_dir * (positions[i] - line_y)) >? 0.0;
- }
-
- concaveness /= positions.size () ;
-
- /*
- Normalize. For dy = 0, the slope ends up as 0 anyway, so the
- scaling of concaveness doesn't matter much.
- */
- if (dy)
- concaveness /= dy;
+ Real concaveness = (calc_concaveness (far_positions, beam_dir)
+ + calc_concaveness (close_positions, beam_dir))/2;
+
me->set_property ("concaveness", scm_from_double (concaveness));
}