Hi David, 2011/10/24 David Nalesnik <david.nales...@gmail.com>
> Hi Harm, > (...) > I haven't tried to break your function :) but the attached file shows one > way you could generalize it to remove the code duplication and work with > more than four beams. (In the example, I've changed the first group to use > 128th notes.) > Many thanks, I knew it could be done. > > The examples that Gould shows (pg. 158) have the peak of the feathered > beams aligned with a stem. I think this would be a useful variation of the > function. It shouldn't be hard to automate: (ly:grob-object grob 'stems) > will get you an array of the stem grobs associated with the beam, and you > could select a particular stem from the array with ly:grob-array-ref. > I did as you suggested (perhaps it could be shorter and more elegant, but it works :)). The argument of the function now aligns the peak with a stem. But you can also enter non-integer values: (grow-beam-var 3.5) centers the peak between the third and the fourth stem. Values like "0" or values greater than the stem-count are faking \override Beam #'grow-direction = #LEFT (RIGHT). (This is not very elegant: switch on the color in \layout). One little problem: With values between 0 and 1 (p.e. 0.5 or 0.8) I retrieve every time the same output. Well, no one would ever enter such strange values and perhaps I'm a little bit paranoic, but could it be, that there's a problem I can't see? Thanks, Harm
\version "2.14.2" \pointAndClickOff #(set-global-staff-size 18) \layout { \context { \Staff \override Beam #'layer = #4 %\override Beam #'color = #red } } \markup \column { \bold \fill-line { "EXAMPLES" } \vspace #2 } xy = \once\override Stem #'french-beaming = ##t #(define ((grow-beam-var number) grob) (if (< (length (cdr (ly:grob-property (ly:grob-parent grob X) 'beaming))) 2) (ly:beam::print grob) (if (ly:stencil? (ly:beam::print grob)) ;; delete this? ;; Thanks to David Nalesnik (let* ((beam (ly:beam::print grob)) (dir (ly:beam::calc-direction grob)) (b-d (ly:output-def-lookup (ly:grob-layout grob) 'blot-diameter)) (beam-extent-X (ly:stencil-extent beam X)) (beam-length-x-orig (interval-length beam-extent-X)) (beam-length-x (- beam-length-x-orig b-d)) (beam-extent-Y (ly:stencil-extent beam Y)) (beam-length-y (interval-length beam-extent-Y)) (orig-beam-thickness (ly:grob-property grob 'beam-thickness)) (beam-count (length (cdr (ly:grob-property (ly:grob-parent grob X) 'beaming)))) ;; the number of beams (space-between-beams (* 0.46 (ly:grob-property grob 'gap))) ;; the space between the beams (orig-beam-length-at-stem (+ (* beam-count orig-beam-thickness)(* (- beam-count 1) space-between-beams))) (beam-positions (ly:grob-property grob 'positions)) (beam-slant (cond ((<= (car beam-positions) (cdr beam-positions)) 1) ;;((= (car beam-positions) (cdr beam-positions)) 0) ((> (car beam-positions) (cdr beam-positions)) -1))) (orig-slope (* beam-slant (/ (- beam-length-y orig-beam-length-at-stem) beam-length-x))) (alpha (atan orig-slope)) (beam-thickness (* 0.8 orig-beam-thickness)) (h-max (- (/ orig-beam-length-at-stem (cos alpha)) (* 1.3 beam-thickness))) ;;;;; (number-a (if (integer? (abs number)) (abs number) (inexact->exact (floor (abs number))))) (number-b (- (abs number) (floor (abs number)))) (stems (ly:grob-object grob 'stems)) (stem-count (ly:grob-array-length stems)) (refp (ly:grob-system grob)) (first-stem (ly:grob-array-ref stems 0)) (target-stem (if (< (abs number-a) stem-count) (ly:grob-array-ref stems number-a) (ly:grob-array-ref stems (- stem-count 1 )))) (next-stem (if (< (+ (abs number-a) 1) stem-count) (ly:grob-array-ref stems (+ number-a 1)) (ly:grob-array-ref stems (- stem-count 1 )))) (first-stem-coord (ly:grob-relative-coordinate first-stem refp X)) (target-stem-coord (ly:grob-relative-coordinate target-stem refp X)) (next-stem-coord (ly:grob-relative-coordinate next-stem refp X)) (first-stem-to-target-stem-length (interval-length (cons first-stem-coord target-stem-coord))) (stem-to-next-stem-length (interval-length (cons target-stem-coord next-stem-coord))) (factor (if (= first-stem-to-target-stem-length 0) beam-length-x (/ beam-length-x first-stem-to-target-stem-length))) ;; markup-a is the longest beam (markup-a (markup #:beam beam-length-x orig-slope beam-thickness)) ;; left piece ;; y-length of left piece (y-L (lambda (n) (- (/ (- beam-length-y orig-beam-length-at-stem) factor) (* dir beam-slant (* n (/ h-max (- beam-count 1))))) )) ;; x-length of left piece (x-L (if (= first-stem-to-target-stem-length 0) 0.001 (+ first-stem-to-target-stem-length (* number-b stem-to-next-stem-length)))) ;; slope of left piece (slope-part-beam-L (lambda (n) (cond ((or (and (> dir 0) (> beam-slant 0)) (and (< dir 0) (> beam-slant 0))) (/ (y-L n) x-L)) ((or (and (> dir 0) (< beam-slant 0)) (and (< dir 0) (< beam-slant 0))) (* -1 (/ (y-L n) x-L)))))) ;; construct left piece (part-beam-L (lambda (n) (markup #:beam x-L (slope-part-beam-L n) beam-thickness))) ;; markup of left piece (markup-L (lambda (n) (markup (part-beam-L n)))) ;; stencil of left piece (beam-part-L (lambda (n) (grob-interpret-markup grob (markup-L n)))) ;; y-extent of left piece (beam-part-L-ext-y (lambda (n) (ly:stencil-extent (beam-part-L n) Y))) ;; length of left piece (length-beam-part-L-y (lambda (n) (interval-length (beam-part-L-ext-y n)))) ;; right piece (y-R (lambda (n) (- (- beam-length-y orig-beam-length-at-stem) (y-L n)))) (x-R (- beam-length-x x-L)) (slope-part-beam-R (lambda (n) (cond ((or (and (> dir 0) (> beam-slant 0)) (and (< dir 0) (> beam-slant 0))) (/ (y-R n) x-R)) ((or (and (> dir 0) (< beam-slant 0)) (and (< dir 0) (< beam-slant 0))) (* -1 (/ (y-R n) x-R)))))) (part-beam-R (lambda (n) (markup #:beam (- beam-length-x x-L) (slope-part-beam-R n) beam-thickness))) (markup-R (lambda (n) (markup (part-beam-R n)))) ;; parts of feathered beams (beam-pieces (map (lambda (n) (ly:stencil-combine-at-edge (ly:stencil-translate-axis (grob-interpret-markup grob (markup-L n)) -0.025 X) X RIGHT (ly:stencil-translate-axis (grob-interpret-markup grob (markup-R n)) (cond ((and (> dir 0)(> beam-slant 0)) (if (and (>= (slope-part-beam-L n) 0)(>= (slope-part-beam-R n) 0)) (- (length-beam-part-L-y n) beam-thickness) (* -1 (- (length-beam-part-L-y n) beam-thickness)))) ((and (> dir 0)(< beam-slant 0)) (* -1 (- (length-beam-part-L-y n) beam-thickness))) ((and (< dir 0)(> beam-slant 0)) (- (length-beam-part-L-y n) beam-thickness)) ((and (< dir 0)(< beam-slant 0)) (if (and (<= (slope-part-beam-L n) 0)(<= (slope-part-beam-R n) 0)) (* -1 (- (length-beam-part-L-y n) beam-thickness)) (- (length-beam-part-L-y n) beam-thickness))) ) Y) 0)) (cdr (iota beam-count)))) ) ;; end of defs in let* (define (helper beam-pieces) (ly:stencil-add (car beam-pieces) (if (null? (cdr beam-pieces)) (car beam-pieces) (helper (cdr beam-pieces))))) (ly:stencil-translate-axis (ly:stencil-add ;; first (long beam) (ly:stencil-translate-axis (grob-interpret-markup grob markup-a) -0.025 X) ;; other beams (helper beam-pieces)) (car beam-positions) Y) ) ;; end of let* #f) ) ) %--------------------- Test ---------------------------------------------------- \relative c' { \mark\markup { \with-color #red "A" } \once \override Beam #'stencil = #(grow-beam-var 0.5) c512[ d e f g a b c] s128 \mark\markup { \with-color #red "B" } \once \override Beam #'stencil = #(grow-beam-var 5) c,32[ d e f g a b c] \mark\markup { \with-color #red "C" } \once \override Beam #'stencil = #(grow-beam-var 3.5) a64[ g f e d c b a] \mark\markup { \with-color #red "D" } \once\override Beam #'stencil = #(grow-beam-var 5) c,32 [c c c c c c c c c c c c c c c ] \bar "" \break \mark\markup { \with-color #red "E" } \once \override Beam #'stencil = #(grow-beam-var 5) c''32 [d' e, f g a b, c d'' e f g, a b c d ] \mark\markup { \with-color #red "F" } \once \override Beam #'stencil = #(grow-beam-var 5) c,,32 [d e f g a b c d e f g a b c d ] \bar ""\break \mark\markup { \with-color #red "G" } \once \override Beam #'stencil = #(grow-beam-var 5) c32 [b a g f e d c b a g f e d c b ] \mark\markup { \with-color #red "H" } \once\override Beam #'stencil = #(grow-beam-var 5) c,32 [c' c' c,, c d e f g c e b' c' ] \bar ""\break \mark\markup { \with-color #red "J" } \once \override Beam #'stencil = #(grow-beam-var 5) c,,,32[ e g b d f a c] \mark\markup { \with-color #red "K" } \once\override Beam #'stencil = #(grow-beam-var 5) c,,256[c' c' c' c'] \bar "" \break \mark\markup { \with-color #red "L" } \once \override Beam #'positions = #'(1 . 1) %\once \override Beam #'stencil = #(grow-beam-var 5) f,,,,,32 [ \xy f''' f,,, \xy f''' f,,, \xy f''' f,,, \xy f''' f,,, \xy f''' f,,,] \override Beam #'auto-knee-gap = #6 f [f'' f,, f'' f,, f'' f,, f''] } % --> http://lsr.dsi.unimi.it/LSR/Item?id=508 \new PianoStaff << \new Staff = "RH" { \clef treble \time 3/4 s2 } \new Staff = "LH" { \clef bass \time 3/4 s2 } \context Staff = LH \relative { \mark\markup { \column { \vspace #3 \with-color #red "M" } } \stemDown \once\override Beam #'stencil = #(grow-beam-var 5) \override Beam #'concaveness = #0 c,,32 [ g' \change Staff = RH d' a' e' b' fis' cis'] \once\override Beam #'stencil = #(grow-beam-var 5) cis32 [fis, b, e, a, d, \change Staff = LH g, c, ] } >> one = \relative c' { \once\override Beam #'stencil = #(grow-beam-var 5) c'32 [c c c c c c c c c c c c c c c] c2 } two = \relative c' { \once\override Beam #'stencil = #(grow-beam-var 5) c,16 [c c c c c c c c c c c c c c c] } <<{ \one } \\ {\two }>> expr = { a1*1/8\< s4.\! s8\> s s s8\! } \relative c'' { \mark\markup { \column { \vspace #3 \with-color #red "N" } } \override Hairpin #'minimum-length = #5 \override Beam #'stencil = #(grow-beam-var 5) a1*1/8\< s4.\! s8\> s s s8\! a16 [a a a a a a a a a a a a a a a] a32 [a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a] a64 [a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a] a2 }
_______________________________________________ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user