+2002-03-11 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ * scm/grob-description.scm (Beam): Add concaveness. Replace
+ Beam::cancel_suspect_slope with Beam::check_concave.
+
+ * lily/beam.cc (check_concave): Calculate concaveness of beam, and
+ set slope to horizontal if concaveness > Beam.concaveness. This
+ handles cases that kludgy cancel_suspect_slope was meant to catch
+ very well.
+ (cancel_suspect_slope): Remove.
+
2002-03-11 Han-Wen <hanwen@cs.uu.nl>
* lily/grob.cc (warning): Use cause tracking to give more
@lilypondfile[printfilename]{beaming.ly}
+@lilypondfile[printfilename]{beam-concave.ly}
+
@lilypondfile[printfilename]{beam-extreme.ly}
@lilypondfile[printfilename]{beam-position.ly}
MAJOR_VERSION=1
MINOR_VERSION=5
PATCH_LEVEL=38
-MY_PATCH_LEVEL=
+MY_PATCH_LEVEL=jcn1
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
measure 25, we get back the linebreaking of Baerenreiter.
This file used to show spacing weaknesses. Now it shows weaknesses in
-beam and slur handling.
-
-Note that the Barenreiter edition contains a mistake. The second line
-begins with measure 6, not 5. "
-
+beam and slur handling."
}
{ d4 a2 } >
f4. [e8 d c] |
[bes g'] [f e16(f] [g a bes)d,] |
- cis4.-\trill b8 a g |
+ cis4.-\trill [b8 a g] |
% check spacing without accs:
% c4.-\trill [bes8 a g] |
< { d'8. e16 f4.-\trill d16 e |
- f4. d8 e f }
+ f4. [d8 e f] }
\\
{ <a,4 f> a2 <a4. d,4.> } > |
%5
fis8.-\trill es16 d8 c |
[bes g'] [a, fis'] [es' d] |
%16
- < bes4.-\trill d, g, > a8 g f! |
+ < bes4.-\trill d, g, > [a8 g f!] |
e bes a f' g a |
d, as g es' f g |
[cis, bes'] [a g16 f] [e!8 f16 d] |
\\
{ f,4 fis4. s8 |
<d4 g,> gis4. } >
- d16(cis)d f, a,8 e' d' cis |
+ d16(cis)d f, [a,8 e'] [d' cis] |
d4 d,,2 |
}
--- /dev/null
+\header{
+ texidoc = "Concave beams should be horizontal. However, what exactly
+it is that makes a beam concave is still unclear.
+
+Beams 1 and 3 should be sloped, 2 and 4 should be horizontal. Two
+sane attempts of calculating concaveness of a beam fail to distinguish
+beams this way."
+
+}
+
+\score{
+ \notes\relative c'{
+ \property Voice.Beam \set #'debug-concave = ##t
+
+%%% \property Voice.Beam \set #'concaveness = #0.8
+%%% \property Voice.Beam \set #'concaveness-no-slope = ##f
+%%% \property Voice.Beam \set #'concaveness-square = ##f
+
+
+
+ \property Voice.Beam \set #'concaveness-no-slope = ##t
+ %%\property Voice.Beam \set #'concaveness = #0.25
+
+ %% this gives what baerenreiter does, but it's too kludgy
+ %% to make much sense
+ \property Voice.Beam \set #'concaveness-square = ##t
+ \property Voice.Beam \set #'concaveness = #0.08
+
+%% This case seems easy: second beam should be horizontal.
+
+ %% SCS-I Menuet I, m15
+ %% sloped
+ %% slope = -0.5ss
+ %% concaveness: 0.50
+ %% concaveness-no-slope: 0.25
+ %% concaveness-no-slope^2: 0.06
+ \clef bass
+ \time 3/4
+ \key g\major
+ a8 g fis e b dis
+
+ %% SCS-I Menuet II, m20
+ %% horizontal
+ %% slope = 0
+ %% concaveness: 1.12
+ %% concaveness-no-slope: 0.38
+ %% concaveness-no-slope^2: 0.09
+ \key f\major
+ fis,^"horiz." a c es d c
+
+%%% Sarabande: the first beam, obviously more concave, is not horizontal,
+%%% but is matched with the next beam in the piece: context.
+
+ %% Sarabande: m24
+ %% sloped
+ %% concaveness: 0.75
+ %% concaveness-no-slope: 0.00
+ %% concaveness-no-slope^2: 0.00
+ \stemUp
+ [d,16 a' b cis]
+
+ %% Sarabande: m25
+ %% horizontal
+ %% concaveness: 0.50
+ %% concaveness-no-slope: 0.25
+ %% concaveness-no-slope^2: 0.12
+ [a'16^"horiz." b c b]
+
+% Hmm. Concaveness of both: 1.75
+% %% SCS-VI Prelude, m81
+% %% slope = 0.0
+% \stemBoth
+% \key d\major
+% [e,8 cis a']
+
+% %% SCS-VI Prelude, m82
+% %% slope = 0.1ss (possibly b.o. context?)
+% [g, e' cis]
+
+ }
+ \paper{
+ linewidth = -1.0
+ }
+}
+
+%% Local variables:
+%% LilyPond-indent-level:2
+%% End:
return SCM_UNSPECIFIED;
}
-MAKE_SCHEME_CALLBACK (Beam, cancel_suspect_slope, 1);
+#include <stdio.h>
+MAKE_SCHEME_CALLBACK (Beam, check_concave, 1);
SCM
-Beam::cancel_suspect_slope (SCM smob)
+Beam::check_concave (SCM smob)
{
Grob *me = unsmob_grob (smob);
+
+ Link_array<Item> stems =
+ Pointer_group_interface__extract_grobs (me, (Item*) 0, "stems");
+
+ for (int i = 0; i < stems.size ();)
+ {
+ if (Stem::invisible_b (stems[i]))
+ stems.del (i);
+ else
+ i++;
+ }
- if (visible_stem_count (me) <= 1)
+ if (stems.size () < 3)
return SCM_UNSPECIFIED;
+
+ SCM s = me->get_grob_property ("concaveness-no-slope");
+
+ Real concave = 0;
+ if (!to_boolean (s))
+ {
+ /* Concaveness try #1: Sum distances of inner noteheads to line
+ between two outer noteheads. */
+
+ Real dy = Stem::chord_start_f (stems.top ())
+ - Stem::chord_start_f (stems[0]);
+ Real slope = dy / (stems.size () - 1);
+
+ Real y0 = Stem::chord_start_f (stems[0]);
+ for (int i = 1; i < stems.size () - 1; i++)
+ {
+ Real c = (Stem::chord_start_f (stems[i]) - y0) - i * slope;
+ concave += c;
+ }
+
+ }
+ else
+ {
+ /* Concaveness try #2: Sum distances of inner noteheads that
+ fall outside the interval of the two outer noteheads */
+
+ Interval iv = Interval (Stem::chord_start_f (stems[0]),
+ Stem::chord_start_f (stems.top ()));
+
+ if (iv[MAX] < iv[MIN])
+ // iv.swap ();
+ iv = Interval (iv[MAX], iv[MIN]);
+
+ for (int i = 1; i < stems.size () - 1; i++)
+ {
+ Real c = 0;
+ Real f = Stem::chord_start_f (stems[i]);
+ if ((c = f - iv[MAX]) > 0)
+ concave += c;
+ else if ((c = f - iv[MIN]) < 0)
+ concave += c;
+ }
+ }
- /* Stem_info, and thus y,dy in this function are corrected for beam-dir */
- Direction dir = Directional_element_interface::get (me);
- Real y = gh_scm2double (me->get_grob_property ("y")) * dir;
- Real dy = gh_scm2double (me->get_grob_property ("dy")) * dir;
-
- /* steep slope running against lengthened stem is suspect */
- Real first_ideal = Stem::calc_stem_info (first_visible_stem (me)).idealy_f_;
- Real last_ideal = Stem::calc_stem_info (last_visible_stem (me)).idealy_f_;
- Real lengthened = gh_scm2double (me->get_grob_property ("outer-stem-length-limit"));
- Real steep = gh_scm2double (me->get_grob_property ("slope-limit"));
+ concave *= Directional_element_interface::get (me);
+
+ Real concaveness = concave / (stems.size () - 2);
- // ugh -> use commonx
- Real dx = last_visible_stem (me)->relative_coordinate (0, X_AXIS) - first_visible_stem (me)->relative_coordinate (0, X_AXIS);
- Real dydx = dy && dx ? dy/dx : 0;
+ /* ugh: this is the a kludge to get input/regression/beam-concave.ly
+ to behave as baerenreiter. */
+ s = me->get_grob_property ("concaveness-square");
+ if (to_boolean (s))
+ concaveness /= (stems.size () - 2);
+
+ s = me->get_grob_property ("concaveness");
+ Real r = gh_scm2double (s);
- if (( (y - first_ideal > lengthened) && (dydx > steep))
- || ((y + dy - last_ideal > lengthened) && (dydx < -steep)))
+ if (concaveness > r)
{
+ Direction dir = Directional_element_interface::get (me);
+ Real y = gh_scm2double (me->get_grob_property ("y")) * dir;
+ Real dy = gh_scm2double (me->get_grob_property ("dy")) * dir;
+
Real adjusted_y = y + dy / 2;
/* Store true, not dir-corrected values */
me->set_grob_property ("y", gh_double2scm (adjusted_y * dir));
me->set_grob_property ("dy", gh_double2scm (0));
}
+
+ s = me->get_grob_property ("debug-concave");
+ if (to_boolean (s))
+ {
+#if 0
+ Item *text = new Item (me->get_property ("TextScript"));
+ text->set_grob_property ("text",
+ ly_str02scm (to_str (concaveness).ch_C ())),
+ Side_position_interface::add_support (text, stem[0]);
+#else
+ printf ("concaveness: %.2f\n", concaveness);
+#endif
+ }
+
return SCM_UNSPECIFIED;
}
y-dy callbacks
*/
DECLARE_SCHEME_CALLBACK (least_squares, (SCM));
- DECLARE_SCHEME_CALLBACK (cancel_suspect_slope, (SCM));
+ DECLARE_SCHEME_CALLBACK (check_concave, (SCM));
DECLARE_SCHEME_CALLBACK (slope_damping, (SCM));
DECLARE_SCHEME_CALLBACK (quantise_dy, (SCM));
DECLARE_SCHEME_CALLBACK (user_override, (SCM));
% input feta-bolletjes;
% input feta-banier;
% input feta-eindelijk;
-% input feta-klef;
-% input feta-toevallig;
+ input feta-klef;
+ input feta-toevallig;
% input feta-schrift;
% input feta-haak;
% input feta-timesig;
;; todo: clean this up a bit: the list is getting
;; rather long.
(molecule-callback . ,Beam::brew_molecule)
+;; (concaveness . 0.8)
+ (concaveness . 0.08)
+ (concaveness-no-slope . #t)
+ (concaveness-square . #t)
(y-dy-callbacks . (,Beam::least_squares
- ,Beam::cancel_suspect_slope
+ ,Beam::check_concave
,Beam::slope_damping
,Beam::quantise_dy
,Beam::user_override