Deutsches Lilypond Forum (Archiv)
Allgemein => Fragen zu Funktionen => Thema gestartet von: kilgore am Donnerstag, 29. September 2011, 17:31
-
Liebe Lilys!
grow-direction kann man leicht einstellen für links oder rechts, aber was ist, wenn eine Gruppe von Tönen erst allmählich schneller, und dann allmählich langsamer gespielt werden sollen?
Anbei sind ein paar Beispiele, und meine Versuche das irgendwie abzubilden. Kennt jemand da eine gute Lösung?
Danke!
Gruß
kil
\version "2.14.2"
\relative c' {
\once \override Beam #'grow-direction = #RIGHT
c32[ c c c]
\once \override Beam #'grow-direction = #LEFT
c[ c c c]
\once \override Beam #'grow-direction = #RIGHT
c32[ c c c
\once \override Beam #'grow-direction = #LEFT
c c c c]
}
\relative c' {
\once \override Beam #'grow-direction = #RIGHT
d32[ d d d d]
\once \override Beam #'grow-direction = #LEFT
\override NoteHead #'extra-offset = #'( -2.5 . 0 )
\override Stem #'extra-offset = #'( -2.5 . 0 )
\override Beam #'extra-offset = #'( -2.5 . 0 )
\once \override NoteHead #'transparent = ##t
\once \override Stem #'transparent = ##t
d[ d d d]
}
\relative c' {
\once \override Beam #'grow-direction = #RIGHT
c32[ c c
\set stemRightBeamCount = #3
c]
\once \override Beam #'grow-direction = #LEFT
\set stemLeftBeamCount = #3
c[ c c c]
}
-
Hallo kil,
grow-direction scheint ja nur in eine Richtung zu funktionieren.
Es geht vielleicht, indem man den stencil neu definiert. Aber bevor ich mich dran gebe es auch nur zu versuchen (keine Garantie für Erfolg), bestätige doch bitte, daß das angehängte Bild ungefähr Deinem Wunsch entspricht.
Gruß,
Harm
P.S. Der Code mit dem ich es erzeugt habe ist es nicht wert gepostet zu werden: viel zu mühsam und bei der geringsten layout-Änderung funktioniert er schon nicht mehr.
-
Liebe Harm,
Gute Versuch! Es entspricht fast das was ich möchte. Da sollten alle Beams, also in diesem Fall alle drei, zusammen kommen in der Mitte (oder auch nicht in der Mitte). Bei deinem Beispiel würde es zB zu einer Sptize kommen zwischen den vierten und fünften 16tel. Die Spitze kann auch über einen Ton sein, statt zwischen zwei. Macht das Sinn?
Gruß
kil
-
Hallo kil,
ich werde mal meinen Notenschrank durchforsten, ob ich ein Beispiel finde.
Als ich schrieb es müßte über den stencil machbar sein, war das erstmal eine rein theoretische Aussage, denn eigentlich ist via stencil immer alles möglich. Ob man es dann auch hinbekommt ist natürlich eine andere Frage.
Hilfreich wäre, wenn ich wüßte wie grow-direction für beams definiert ist. Ich habs aber auf die Schnelle nicht gefunden.
Weiß jemand wo man nachschauen kann?
Gruß,
Harm
-
Lieber Harm
Danke füe deine Mühe! Ich habe auch meine Lilypond Ordern durchsucht und fand auch nichts.... Hoffentlich weiss es jemand!
Gruß
kil
-
Hallo kil,
mein erster Versuch das Procedere mit nur wenigen Variablen quasi automatisiert zu definieren ist leider gescheitert.
Es gibt für Stem und Beam eine Unzahl von Ausgleichsvariablen, die schlecht oder gar nicht kommentiert sind. (siehe IR Stem bzw. Beam und dort: details ) Sie haben natürlich alle einen Sinn, denn nicht umsonst liefert lily schon so einen hervorragenden default-output.
Diese Variablen aber alle in einer eigenen Definition zu berücksichtigen, würde wahrscheinlich dazu führen, daß ich nächstes Jahr noch damit beschäftigt wäre.
So kriegst Du jetzt eine Fassung mit einer Unmenge von Variablen ;). Sie sind alle ausgleichender bzw anpassender Natur. Es muß also kein Wert gänzlich neu erraten werden, sondern die errechneten Werte können angepaßt werden. (Das ist Arbeit genug). Der Code ist recht ausführlich kommentiert und es gibt eine "Step-by-Step-Demonstration" in einem zweiten Score, so daß eigentlich klar werden sollte, wie vorzugehen ist. Wenn nicht, dann frag. :)
Die von mir im ersten Score benutzten Werte kann man wahrscheinlich noch besser einstellen, aber das fein-tunen nur für ein Snippet war mir dann zu aufwendig.;)
Ich hoffe es kommt dem zumindest nahe, was Dir vorschwebt.
\version "2.14.2"
\markup \column { \bold \fill-line { "EXAMPLE" } \vspace #2 }
#(define ((grow-dir-var top y-offset corr-y slope-1 slope-2 slope-3) grob)
(cond ((= top 1) (and (display "\n ______________No Top wanted?________________________") #f))
((< top 1) (and (display "\n ______________No reachable Top!_____________________") #f))
((> top 1)
(if (ly:stencil? (ly:beam::print grob))
(let* ((beam (ly:beam::print grob))
(dir (ly:beam::calc-direction grob))
(beam-extent-X (ly:stencil-extent beam X))
(beam-length-x (interval-length beam-extent-X))
(beam-extent-Y (ly:stencil-extent beam Y))
(beam-length-y (interval-length beam-extent-Y))
(line-thickness (ly:output-def-lookup (ly:grob-layout grob) 'line-thickness))
(beam-thickness (* 0.48 (ly:output-def-lookup (ly:grob-layout grob) 'staff-space)))
(half-stem-thickness (/ (* 1.3 line-thickness) 2))
(space-helper (/ beam-length-y (/ beam-length-x 1.5)))
;; markup-a is the longest beam
(markup-a (markup #:beam (- beam-length-x (* half-stem-thickness 1.26)) ;; length
(if (or (> 0 (cdr beam-extent-Y)) (equal? dir 1)) ;; slope
(+ (car slope-1) 0)
(+ (car slope-1) (cdr beam-extent-Y)))
beam-thickness)) ;; thickness
(long-beam (grob-interpret-markup grob markup-a))
(long-beam-ext-y (ly:stencil-extent long-beam Y))
(long-beam-ext-x (ly:stencil-extent long-beam X))
;; markup-b is begin of the first additional beam
(part-beam-1 (markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 1.4)) ;; length
(if (> 0 (cdr beam-extent-Y)) ;; slope
(+ (car slope-2) (* dir (/ space-helper -1 )))
(+ (car slope-2) (* dir (/ space-helper -0.8))))
beam-thickness)) ;; thickness
(markup-b (markup part-beam-1))
(first-part-beam-1 (grob-interpret-markup grob markup-b))
(first-part-beam-1-ext-y (ly:stencil-extent first-part-beam-1 Y))
(length-first-part-beam-1-y (interval-length first-part-beam-1-ext-y))
(first-part-beam-1-ext-x (ly:stencil-extent first-part-beam-1 X))
;; markup-bb is the end of the first additional beam
(part-beam-11 (markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 1.4)) ;; length
(if (> 0 dir) ;; slope
(+ (cdr slope-2) (* dir (/
(- (cdr first-part-beam-1-ext-y) (cdr long-beam-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-1-ext-x))
)))
(+ (cdr slope-2) (* dir (/
(- (cdr long-beam-ext-y)(cdr first-part-beam-1-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-1-ext-x))
))))
beam-thickness)) ;; thickness
(markup-bb (markup part-beam-11))
;; markup-c is the begin of the second additional beam
(part-beam-2
(if (not (equal? (car slope-3) #f))
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 1.4)) ;; length
(if (> 0 (cdr beam-extent-Y)) ;; slope
(+ (car slope-3) (* dir (/ space-helper -2)))
(+ (car slope-3) (* dir (/ space-helper -1.2))))
beam-thickness) ;; thickness
(markup #:null)))
(markup-c (markup part-beam-2))
(first-part-beam-2 (grob-interpret-markup grob markup-c))
(first-part-beam-2-ext-y (ly:stencil-extent first-part-beam-2 Y))
(length-first-part-beam-2-y (interval-length first-part-beam-2-ext-y))
(first-part-beam-2-ext-x (ly:stencil-extent first-part-beam-2 X))
;; markup-cc is the end of the second additional beam
(part-beam-22
(if (not (equal? (cdr slope-3) #f))
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 1.4)) ;;length
(if (> 0 dir) ;;slope
(+ (cdr slope-3)
(* dir (/
(- (cdr first-part-beam-2-ext-y) (cdr long-beam-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-2-ext-x))
)))
(+ (cdr slope-3)
(* dir (/
(- (cdr long-beam-ext-y) (cdr first-part-beam-2-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-2-ext-x))
))))
beam-thickness) ;; thickness
(markup #:null)))
(markup-cc (markup part-beam-22))
) ;; end of defs in let*
(ly:stencil-translate-axis
(ly:stencil-add
;; first (long beam)
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-a)
(/ half-stem-thickness -2.7)
X)
;; parts of second beam
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-b)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-bb)
(+ (car corr-y)
(if (> 0 dir)
(- (cdr first-part-beam-1-ext-y) (* 0.5 beam-thickness))
(* -1 (- length-first-part-beam-1-y (* 1 beam-thickness)))))
Y)
0)
;; parts of third beam
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-c)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-cc)
(+ (cdr corr-y)
(if (equal? dir -1)
(- (cdr first-part-beam-2-ext-y) (* 0.5 beam-thickness))
(* -1 (- length-first-part-beam-2-y beam-thickness))))
Y)
0)
) ;; end of stencil-add
(if (equal? dir 1)
(+ y-offset 0)
(if (> 0 (cdr beam-extent-Y))
(+ y-offset -3.3)
(+ y-offset -1.8)))
Y)
) ;; end of let*
#f))))
%--------------------- Test ----------------------------------------------------
\layout {
\context {
\Score
\override NonMusicalPaperColumn #'line-break-permission = ##f
}
}
\relative c' {
\once \override Beam #'stencil = #(grow-dir-var 3 ; where to print the turn (2 is half-beam)
-0.2 ; Y-offset of the whole construct
'(0 . 0) ; additional Y-offset
; '(<second part of the first added beam>
; .
; <second part of the second added beam>)
'(0 . 0) ; slope of the long beam (without) top
'(-0.01 . 0) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(0.1 . 0)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the second additional
% beam use '(#f . #f)
c'32 [d' e, f g a b, c d'' e f g, a b c d
]
\once \override Beam #'stencil = #(grow-dir-var 3 -1.1 '(0 . 0) '(-0.02 . 0) '(-0.028 . 0) '(0.09 . 0))
c,,32 [d e f g a b c d e f g a b c d
]
\break
\once \override Beam #'stencil = #(grow-dir-var 3 0 '(0 . 0) '(-0.1 . 0) '(-0.17 . -0.07) '(-0.009 . -0.07))
c32 [b a g f e d c b a g f e d c b
]
\once\override Beam #'stencil = #(grow-dir-var 3.5 1 '(0 . 0) '(0 . 0) '(0.0285 . 0.034) '(-0.1 . 0.07))
c,,32 [c c c c c c c c c c c c c c c
]
\once\override Beam #'stencil = #(grow-dir-var 1.3 5.5 '(0.255 . 0) '(0.06 . 0.0) '(0.26 . 0) '(0.13 . 0.12))
c32 [c' c' c,, c d e f g c e b' c'
]
}
%\pageBreak
\markup \column { \vspace #2 \bold \fill-line { "Step-By-Step-Demonstration" } \vspace #2 }
\relative c' {
% Die Spitze kommt z.B. in die Mitte (top -> 2)
\once\override Beam #'stencil = #(grow-dir-var 2 0 '(0 . 0) '(0 . 0) '(0 . 0) '(0 . 0))
c32 [c' c' c, c d e f g c e b' c'
]
% Die linke Ecke des ganzen Balkens wird ausgerichtet (y-offset -> -3)
\once\override Beam #'stencil = #(grow-dir-var 2 -3 '(0 . 0) '(0 . 0) '(0 . 0) '(0 . 0))
c,,,,32 [c' c' c, c d e f g c e b' c'
]
\bar "" \break
% Die rechte Ecke des ganzen Balkens wird ausgerichtet (slope-1 -> '(0.04 . 0))
\once\override Beam #'stencil = #(grow-dir-var 2 -3 '(0 . 0) '(0.04 . 0) '(0 . 0) '(0 . 0))
c,,,,32 [c' c' c, c d e f g c e b' c'
]
% Die Steigung des ersten zusätzlichen Balkens wird ausgerichtet (slope-2 -> '(-0.05 . 0))
% Damit der zweite Balken nicht stört wird er mittels '(#f . #f) ausgeschlossen.
\once\override Beam #'stencil = #(grow-dir-var 2 -3 '(0 . 0) '(0.04 . 0) '(-0.05 . 0) '(#f . #f))
c,,,,32 [c' c' c, c d e f g c e b' c'
]
\bar "" \break
% Die Steigung des zweiten zusätzlichen Balkens wird ausgerichtet (slope-3 -> '(0.05 . 0))
\once\override Beam #'stencil = #(grow-dir-var 2 -3 '(0 . 0) '(0.04 . 0) '(-0.05 . 0) '(0.05 . 0))
c,,,,32 [c' c' c, c d e f g c e b' c'
]
% Andere Veränderungen waren hier nicht nötig!
\once\override Beam #'stencil = #(grow-dir-var 2 -3 '(0 . 0) '(0.04 . 0) '(-0.05 . 0) '(0.05 . 0))
c,,,,32 [c' c' c, c d e f g c e b' c'
]
\bar "" \break
% Leider führt jede Veränderung (wie der gerade erfolgte \break) zu anderen Werten)
\once\override Beam #'stencil = #(grow-dir-var 2 -3 '(0 . 0) '(0.02 . 0) '(-0.025 . 0) '(0.025 . 0))
c,,,,32 [c' c' c, c d e f g c e b' c'
]
}
% An diesem Beispiel mit LilyPond default-Befehlen zeigt sich allerdings,
% daß auch bessere Leute Schwierigkeiten haben. :)
% Hohe Vergrößerung auf die rechte obere Ecke des Balkens zeigt ein Überstehen eines Balkens!
\relative c' {
\once \override Beam #'grow-direction = #LEFT
c,32[ d e f]
}
Desweiteren ist mir bislang keine Partitur in die Hände gefallen in der sowas wie oben vorkommt. (Mag natürlich auch allein an meiner Beschränktheit liegen). Ich habe allerdings häufig etwas gesehen wie im Anhang: beam-bild.png.
Gruß,
Harm
P.S.:Im übrigen ist mir aufgefallen, daß es bei \once \override Beam #'grow-direction = #LEFT (also einem default-Befehl) bei hoher Vergrößerung (sichtbar ab ca 800%) eine unsaubere Graphik gibt. (Es scheint, nicht nur ich habe da Schwierigkeiten. :) ) siehe Anhang: beamsTwo-from-1.1.16-to-1.1.8-clip.pdf.
-
Oh Harm wie großartig!!! Deine Scheme Fähigkeiten sind echt erstaunlich! Ich muss mich später heute mit den Details auseinandersetzen, aber erstmal bin ich schwer beeindruckt. Ich werde versuchen ein paar Beispiele aus der Praxis zu finden...ich weiss ich bin so was schon ein paar mal begegnet....
;D ;D ;D
U Rock!!
Gruß
kil
-
Hallo kil,
ich hoffe Du bist immer noch begeistert, wenn Du es erst mal ausprobiert hast. ;)
Gruß,
Harm
-
Naja, erstmal bin ich so weit! Schon gewöhnungsbedürftig, aber es sieht erstmal richtig cool aus!
Die ungenauigkeit am rechten ende des default beams habe ich auch bemerkt, obwohl ich nicht wusste wo der fehler lag!
\version "2.14.2"
\markup \column { \bold \fill-line { "EXAMPLE" } \vspace #2 }
#(define ((grow-dir-var top y-offset corr-y slope-1 slope-2 slope-3) grob)
(cond ((= top 1) (and (display "\n ______________No Top wanted?________________________") #f))
((< top 1) (and (display "\n ______________No reachable Top!_____________________") #f))
((> top 1)
(if (ly:stencil? (ly:beam::print grob))
(let* ((beam (ly:beam::print grob))
(dir (ly:beam::calc-direction grob))
(beam-extent-X (ly:stencil-extent beam X))
(beam-length-x (interval-length beam-extent-X))
(beam-extent-Y (ly:stencil-extent beam Y))
(beam-length-y (interval-length beam-extent-Y))
(line-thickness (ly:output-def-lookup (ly:grob-layout grob) 'line-thickness))
(beam-thickness (* 0.48 (ly:output-def-lookup (ly:grob-layout grob) 'staff-space)))
(half-stem-thickness (/ (* 1.3 line-thickness) 2))
(space-helper (/ beam-length-y (/ beam-length-x 1.5)))
;; markup-a is the longest beam
(markup-a (markup #:beam (- beam-length-x (* half-stem-thickness 1.26)) ;; length
(if (or (> 0 (cdr beam-extent-Y)) (equal? dir 1)) ;; slope
(+ (car slope-1) 0)
(+ (car slope-1) (cdr beam-extent-Y)))
beam-thickness)) ;; thickness
(long-beam (grob-interpret-markup grob markup-a))
(long-beam-ext-y (ly:stencil-extent long-beam Y))
(long-beam-ext-x (ly:stencil-extent long-beam X))
;; markup-b is begin of the first additional beam
(part-beam-1 (markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 1.4)) ;; length
(if (> 0 (cdr beam-extent-Y)) ;; slope
(+ (car slope-2) (* dir (/ space-helper -1 )))
(+ (car slope-2) (* dir (/ space-helper -0.8))))
beam-thickness)) ;; thickness
(markup-b (markup part-beam-1))
(first-part-beam-1 (grob-interpret-markup grob markup-b))
(first-part-beam-1-ext-y (ly:stencil-extent first-part-beam-1 Y))
(length-first-part-beam-1-y (interval-length first-part-beam-1-ext-y))
(first-part-beam-1-ext-x (ly:stencil-extent first-part-beam-1 X))
;; markup-bb is the end of the first additional beam
(part-beam-11 (markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 1.4)) ;; length
(if (> 0 dir) ;; slope
(+ (cdr slope-2) (* dir (/
(- (cdr first-part-beam-1-ext-y) (cdr long-beam-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-1-ext-x))
)))
(+ (cdr slope-2) (* dir (/
(- (cdr long-beam-ext-y)(cdr first-part-beam-1-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-1-ext-x))
))))
beam-thickness)) ;; thickness
(markup-bb (markup part-beam-11))
;; markup-c is the begin of the second additional beam
(part-beam-2
(if (not (equal? (car slope-3) #f))
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 1.4)) ;; length
(if (> 0 (cdr beam-extent-Y)) ;; slope
(+ (car slope-3) (* dir (/ space-helper -2)))
(+ (car slope-3) (* dir (/ space-helper -1.2))))
beam-thickness) ;; thickness
(markup #:null)))
(markup-c (markup part-beam-2))
(first-part-beam-2 (grob-interpret-markup grob markup-c))
(first-part-beam-2-ext-y (ly:stencil-extent first-part-beam-2 Y))
(length-first-part-beam-2-y (interval-length first-part-beam-2-ext-y))
(first-part-beam-2-ext-x (ly:stencil-extent first-part-beam-2 X))
;; markup-cc is the end of the second additional beam
(part-beam-22
(if (not (equal? (cdr slope-3) #f))
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 1.4)) ;;length
(if (> 0 dir) ;;slope
(+ (cdr slope-3)
(* dir (/
(- (cdr first-part-beam-2-ext-y) (cdr long-beam-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-2-ext-x))
)))
(+ (cdr slope-3)
(* dir (/
(- (cdr long-beam-ext-y) (cdr first-part-beam-2-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-2-ext-x))
))))
beam-thickness) ;; thickness
(markup #:null)))
(markup-cc (markup part-beam-22))
) ;; end of defs in let*
(ly:stencil-translate-axis
(ly:stencil-add
;; first (long beam)
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-a)
(/ half-stem-thickness -2.7)
X)
;; parts of second beam
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-b)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-bb)
(+ (car corr-y)
(if (> 0 dir)
(- (cdr first-part-beam-1-ext-y) (* 0.5 beam-thickness))
(* -1 (- length-first-part-beam-1-y (* 1 beam-thickness)))))
Y)
0)
;; parts of third beam
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-c)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-cc)
(+ (cdr corr-y)
(if (equal? dir -1)
(- (cdr first-part-beam-2-ext-y) (* 0.5 beam-thickness))
(* -1 (- length-first-part-beam-2-y beam-thickness))))
Y)
0)
) ;; end of stencil-add
(if (equal? dir 1)
(+ y-offset 0)
(if (> 0 (cdr beam-extent-Y))
(+ y-offset -3.3)
(+ y-offset -1.8)))
Y)
) ;; end of let*
#f))))
%--------------------- Test ----------------------------------------------------
\relative c' {
\once \override Beam #'stencil = #(grow-dir-var 2 ; where to print the turn (2 is half-beam)
0.6 ; Y-offset of the whole construct
'(0 . 0) ; additional Y-offset
; '(<second part of the first added beam>
; .
; <second part of the second added beam>)
'(0 . 0) ; slope of the long beam (without) top
'(0 . .2) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(.04 . .1)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the second additional
% beam use '(#f . #f)
c32[ c c c c c c c]
}
Ich werde erst mal weiterhin damit basteln.....
-
Hallo kil,
Schon gewöhnungsbedürftig
das ist richtig. Und die Schwierigkeiten nehmen zu, wenn der Balken geneigt ist. ;)
Aber als ich mir angesehen habe was Du genau gemacht hast, konnte ich meine Definition noch ein kleines bißchen besser einstellen (das führt natürlich auch zu ein klein wenig veränderten Werten):
\version "2.14.2"
\markup \column { \bold \fill-line { "EXAMPLE" } \vspace #2 }
#(define ((grow-dir-var top y-offset corr-y slope-1 slope-2 slope-3) grob)
(cond ((= top 1) (and (display "\n ______________No Top wanted?________________________") #f))
((< top 1) (and (display "\n ______________No reachable Top!_____________________") #f))
((> top 1)
(if (ly:stencil? (ly:beam::print grob))
(let* ((beam (ly:beam::print grob))
(dir (ly:beam::calc-direction grob))
(beam-extent-X (ly:stencil-extent beam X))
(beam-length-x (interval-length beam-extent-X))
(beam-extent-Y (ly:stencil-extent beam Y))
(beam-length-y (interval-length beam-extent-Y))
(line-thickness (ly:output-def-lookup (ly:grob-layout grob) 'line-thickness))
(beam-thickness (* 0.48 (ly:output-def-lookup (ly:grob-layout grob) 'staff-space)))
(half-stem-thickness (/ (* 1.3 line-thickness) 2))
(space-helper (/ beam-length-y (/ beam-length-x 1.5)))
;; markup-a is the longest beam
(markup-a (markup #:beam (- beam-length-x (* half-stem-thickness 1.25)) ;; length
(if (or (> 0 (cdr beam-extent-Y)) (equal? dir 1)) ;; slope
(+ (car slope-1) 0)
(+ (car slope-1) (cdr beam-extent-Y)))
beam-thickness)) ;; thickness
(long-beam (grob-interpret-markup grob markup-a))
(long-beam-ext-y (ly:stencil-extent long-beam Y))
(long-beam-ext-x (ly:stencil-extent long-beam X))
;; markup-b is begin of the first additional beam
(part-beam-1 (markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.8)) ;; length
(if (> 0 (cdr beam-extent-Y)) ;; slope
(+ (car slope-2) (* dir (/ space-helper -1 )))
(+ (car slope-2) (* dir (/ space-helper -0.8))))
beam-thickness)) ;; thickness
(markup-b (markup part-beam-1))
(first-part-beam-1 (grob-interpret-markup grob markup-b))
(first-part-beam-1-ext-y (ly:stencil-extent first-part-beam-1 Y))
(length-first-part-beam-1-y (interval-length first-part-beam-1-ext-y))
(first-part-beam-1-ext-x (ly:stencil-extent first-part-beam-1 X))
;; markup-bb is the end of the first additional beam
(part-beam-11 (markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.8)) ;; length
(if (> 0 dir) ;; slope
(+ (cdr slope-2) (* dir (/
(- (cdr first-part-beam-1-ext-y) (cdr long-beam-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-1-ext-x))
)))
(+ (cdr slope-2) (* dir (/
(- (cdr long-beam-ext-y)(cdr first-part-beam-1-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-1-ext-x))
))))
beam-thickness)) ;; thickness
(markup-bb (markup part-beam-11))
;; markup-c is the begin of the second additional beam
(part-beam-2
(if (not (equal? (car slope-3) #f))
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.8)) ;; length
(if (> 0 (cdr beam-extent-Y)) ;; slope
(+ (car slope-3) (* dir (/ space-helper -2)))
(+ (car slope-3) (* dir (/ space-helper -1.2))))
beam-thickness) ;; thickness
(markup #:null)))
(markup-c (markup part-beam-2))
(first-part-beam-2 (grob-interpret-markup grob markup-c))
(first-part-beam-2-ext-y (ly:stencil-extent first-part-beam-2 Y))
(length-first-part-beam-2-y (interval-length first-part-beam-2-ext-y))
(first-part-beam-2-ext-x (ly:stencil-extent first-part-beam-2 X))
;; markup-cc is the end of the second additional beam
(part-beam-22
(if (not (equal? (cdr slope-3) #f))
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.8)) ;;length
(if (> 0 dir) ;;slope
(+ (cdr slope-3)
(* dir (/
(- (cdr first-part-beam-2-ext-y) (cdr long-beam-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-2-ext-x))
)))
(+ (cdr slope-3)
(* dir (/
(- (cdr long-beam-ext-y) (cdr first-part-beam-2-ext-y))
(- (cdr long-beam-ext-x) (cdr first-part-beam-2-ext-x))
))))
beam-thickness) ;; thickness
(markup #:null)))
(markup-cc (markup part-beam-22))
) ;; end of defs in let*
(ly:stencil-translate-axis
(ly:stencil-add
;; first (long beam)
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-a)
(/ half-stem-thickness -2.7)
X)
;; parts of second beam
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-b)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-bb)
(+ (car corr-y)
(if (> 0 dir)
(- (cdr first-part-beam-1-ext-y) (* 0.5 beam-thickness))
(* -1 (- length-first-part-beam-1-y (* 1 beam-thickness)))))
Y)
0)
;; parts of third beam
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-c)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-cc)
(+ (cdr corr-y)
(if (equal? dir -1)
(- (cdr first-part-beam-2-ext-y) (* 0.5 beam-thickness))
(* -1 (- length-first-part-beam-2-y beam-thickness))))
Y)
0)
) ;; end of stencil-add
(if (equal? dir 1)
(+ y-offset 0)
(if (> 0 (cdr beam-extent-Y))
(+ y-offset -3.3)
(+ y-offset -1.8)))
Y)
) ;; end of let*
#f))))
%--------------------- Test ----------------------------------------------------
% '(#f . #f)) %
\relative c' {
\once \override Beam #'stencil = #(grow-dir-var 2 ; where to print the turn (2 is half-beam)
0.7 ; Y-offset of the whole construct
'(0 . 0) ; additional Y-offset
; '(<second part of the first added beam>
; .
; <second part of the second added beam>)
'(0 . 0) ; slope of the long beam (without) top
'(0 . .221) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(.04 . .108)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the second additional
% beam use '(#f . #f)
c32[ c c c c c c c]
}
Ich wäre Dir also dankbar, wenn Du weitere Testversuche ebenfalls posten könntest, damit ich dann wieder schauen kann, wie ich meine Funktion noch verbessern kann.
Gruß,
Harm
-
Lieber Harm,
Das Unterschied mit deiner Änderungen sehe ich nicht, aber es liegt wohl in den Details!
Hier ein paar weitere Versuche, obwohl ich schon längst nicht fertig bin mit probieren :)
Ein Problem ist schon aufgetaucht, und zwar in der dritten Zeile. Es geht um diesen Wert:
'(0.3 . .02)) % slope '(<first part of the second added beam>
das 0.3 verursacht (anscheinend) diese Ungenauigkeit wo die beiden Beams sich in der Mitte treffen. Ich habe es lösen können mit einem Wert von 0.29, wollte diesen Beam aber doch ein bisschen höher haben. Warum das so vorkommt kann ich noch nicht erklären, aber vielleicht verstehst du es?
Gruß
kil
-
Hallo kil,
Das Unterschied mit deiner Änderungen sehe ich nicht, aber es liegt wohl in den Details!
Ich hatte das Ganze noch mal mit 6400% Vergrößerung betrachtet und ein paar winzige Ungenauigkeiten bemerkt und dann korrigiert. Die Unterschiede sind mikroskopisch klein. ;)
das 0.3 verursacht (anscheinend) diese Ungenauigkeit wo die beiden Beams sich in der Mitte treffen. Ich habe es lösen können mit einem Wert von 0.29, wollte diesen Beam aber doch ein bisschen höher haben. Warum das so vorkommt kann ich noch nicht erklären, aber vielleicht verstehst du es?
Zunächst mal will es mir vorkommen, als ob Du Beam zwei und drei vertauscht hast. Letztendlich macht das keinen Unterschied, aber die Korrekturwerte vergrößern sich. Insoweit rate ich Dir den dritten Beam erstmal auszuschließen, dann den zweiten einzustellen und erst am Schluß den dritten wieder zuzulassen und einzustellen. Soviel erst mal grundsätzlich.
Warum die Beams manchmal vertikal auseinanderdriften kann ich nicht erklären. Aber um dieses Phänomen ausgleichen zu können hatte ich corr-y als Variable in die Definition eingefügt (im Test-Kommentar als additional Y-offset benannt). Du hast diesen Wert immer auf '(0 . 0) belassen. Schön wenn es so funktioniert, wenn nicht muß man da was ändern.
Hier die veränderten Werte für den ersten Abschnitt der dritten Zeile. Alles andere habe ich nicht verändert:
\once \override Beam #'stencil = #(grow-dir-var 2 ; where to print the turn (2 is half-beam)
2 ; Y-offset of the whole construct
'(0.0915 . 0) ; additional Y-offset '(<second part of the first added beam> . <second part of the second added beam>)
'(0.1 . 0) ; slope of the long beam (without) top
'(0.44 . 0) ; slope '(<first part of the first added beam> . <second part of the first added beam>)
'(0.2 . 0.0905)) % slope '(<first part of the second added beam> . <second part of the second added beam>)
% to delete the second additional beam use '(#f . #f)
c32[ d e f g a b c]
Ansonsten werde ich am Wochenende versuchen das ganze noch zu verbessern (falls ich Zeit dafür finde ;) )
Gruß,
Harm
-
Hallo kil,
hier die neueste Fassung:
\version "2.14.2"
#(set-global-staff-size 20)
\layout {
\context {
\Staff
\override Beam #'layer = #-4
%\override Beam #'color = #red
}
}
\markup \column { \bold \fill-line { "EXAMPLE" } \vspace #2 }
#(define ((grow-dir-var top y-offset corr-y slope-1 slope-2 slope-3) grob)
(cond ((= top 1) (and (display "\n ______________No Top wanted?________________________") #f))
((< top 1) (and (display "\n ______________No reachable Top!_____________________") #f))
((> top 1)
(if (ly:stencil? (ly:beam::print grob))
(let* ((beam (ly:beam::print grob))
(dir (ly:beam::calc-direction grob))
(beam-extent-X (ly:stencil-extent beam X))
(beam-length-x (interval-length beam-extent-X))
(beam-extent-Y (ly:stencil-extent beam Y))
(beam-length-y (interval-length beam-extent-Y))
(line-thickness (ly:output-def-lookup (ly:grob-layout grob) 'line-thickness))
(half-stem-thickness (/ (* 1.3 line-thickness) 2))
(beam-thickness (ly:grob-property grob 'beam-thickness))
(orig-slope (/ (- beam-length-y (+ (* 3 beam-thickness) 0.6)) beam-length-x))
(alpha (atan orig-slope))
(h-max (/ (+ (* 3 beam-thickness) 0.35) (cos alpha)))
;; markup-a is the longest beam
(markup-a (markup #:beam (- beam-length-x (* half-stem-thickness 1.25)) ;; length
(* (car slope-1) orig-slope) ;; slope
beam-thickness)) ;; thickness
;; markup-b is begin of the first additional beam
(y1 (- (/ (- beam-length-y (+ (* 3 beam-thickness) 0.6)) top) (/ h-max 2)))
(x1 (/ (- beam-length-x (* half-stem-thickness 1.25)) top))
(part-beam-1
(if (not (equal? (car slope-2) #f))
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.8)) ;; length
(* (car slope-2) dir (/ y1 x1)) ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-b (markup part-beam-1))
(first-part-beam-1 (grob-interpret-markup grob markup-b))
(first-part-beam-1-ext-y (ly:stencil-extent first-part-beam-1 Y))
(length-first-part-beam-1-y (interval-length first-part-beam-1-ext-y))
;; markup-bb is the end of the first additional beam
(y11 (- (- beam-length-y (+ (* 3 beam-thickness) 0.6)) y1 ))
(x11 (- beam-length-x x1))
(part-beam-11
(if (not (equal? (cdr slope-2) #f))
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.8)) ;; length
(* (cdr slope-2) dir (/ y11 x11)) ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-bb (markup part-beam-11))
;; markup-c is the begin of the second additional beam
(y2 (- (/ (- beam-length-y (+ (* 3 beam-thickness) 0.6)) top) h-max))
(x2 x1)
(part-beam-2
(if (not (equal? (car slope-3) #f))
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.8)) ;; length
(* (car slope-3) dir (/ y2 x2)) ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-c (markup part-beam-2))
(first-part-beam-2 (grob-interpret-markup grob markup-c))
(first-part-beam-2-ext-y (ly:stencil-extent first-part-beam-2 Y))
(length-first-part-beam-2-y (interval-length first-part-beam-2-ext-y))
;; markup-cc is the end of the second additional beam
(y22 (- (- beam-length-y (+ (* 3 beam-thickness) 0.6)) y2 ))
(x22 x11)
(part-beam-22
(if (not (equal? (cdr slope-3) #f))
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.8)) ;;length
(* (cdr slope-3) dir (/ y22 x22)) ;;slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-cc (markup part-beam-22))
) ;; end of defs in let*
(ly:stencil-translate-axis
(ly:stencil-add
;; first (long beam)
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-a)
(/ half-stem-thickness -2.7)
X)
;; parts of second beam
(ly:stencil-in-color
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-b)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-bb)
(* dir (car corr-y) (- length-first-part-beam-1-y beam-thickness))
Y)
0)
0 0 0) ;; <-- coloring
;; parts of third beam
(ly:stencil-in-color
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-c)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-cc)
(* dir (cdr corr-y) (* -1 (- length-first-part-beam-2-y beam-thickness)))
Y)
0)
0 0 0) ;; <-- coloring
) ;; end of stencil-add
(* dir y-offset (- beam-length-y (+ (* 3 beam-thickness) 1)))
Y)
) ;; end of let*
#f))))
%--------------------- Test ----------------------------------------------------
\relative c' {
\mark\markup { \with-color #red "A" }
\once \override Beam #'stencil = #(grow-dir-var 2 ; where to print the turn (2 is half-beam)
1 ; Y-offset of the whole construct
'(1 . 1) ; additional Y-offset
; '(<second part of the first added beam>
; .
; <second part of the second added beam>)
'(1 . 1) ; slope of the long beam (without) top
'(1 . 1) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(1 . 1)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
c32[ d e f g a b c]
\mark\markup { \with-color #red "B" }
\once \override Beam #'stencil = #(grow-dir-var 1.4 ; where to print the turn (2 is half-beam)
1 ; Y-offset of the whole construct
'(1 . 1) ; additional Y-offset
; '(<second part of the first added beam>
; .
; <second part of the second added beam>)
'(1 . 1) ; slope of the long beam (without) top
'(1 . 1) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(1 . 1)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
c,32[ d e f g a b c]
\mark\markup { \with-color #red "C" }
\once \override Beam #'stencil = #(grow-dir-var 2 2.9 '(-1 . 1) '(-1 . 1) '(8 . 0.17) '(2.5 . 0.55))
a32[ g f e d c b a]
\bar "" \break
\mark\markup { \with-color #red "D" }
\once \override Beam #'stencil = #(grow-dir-var 3 ; where to print the turn (2 is half-beam)
-11 ; Y-offset of the whole construct
'(-1 . 1) ; additional Y-offset
; '(<second part of the first added beam>
; .
; <second part of the second added beam>)
'(1 . 1) ; slope of the long beam (without) top
'(1 . 0.85) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(1 . 0.9)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
c'32 [d' e, f g a b, c d'' e f g, a b c d
]
\mark\markup { \with-color #red "E" }
\once \override Beam #'stencil = #(grow-dir-var 3 4.3 '(-1 . 1) '(1 . 1) '(2.5 . 0.1) '(1.6 . 0.45))
c,,32 [d e f g a b c d e f g a b c d
]
\bar ""\break
\mark\markup { \with-color #red "F" }
\once \override Beam #'stencil = #(grow-dir-var 3 1.5 '(-1 . 1) '(-1 . 1) '(1.2 . 1.03) '(1 . 1))
c32 [b a g f e d c b a g f e d c b
]
\mark\markup { \with-color #red "G" }
\once\override Beam #'stencil = #(grow-dir-var 3.5 -2 '(-1 . 1) '(1 . 1) '(1 . 1) '(1 . 1))
c,,32 [c c c c c c c c c c c c c c c
]
\mark\markup { \with-color #red "H" }
\once\override Beam #'stencil = #(grow-dir-var 1.3 4 '(1 . 1) '(1 . 1) '(1 . 1) '(1 . 1))
c32 [c' c' c,, c d e f g c e b' c'
]
}
Ich bin über Winkelfunktionen gegangen, hab' die Korrekturmöglichkeiten über Multiplikation geregelt und den Code teilweise vereinfacht. Das führt dazu, daß es etwas benutzerfreundlicher wird.
Auch wirken sich layout-Änderungen nicht mehr so stark aus (manchmal sind sie so gering, daß eine Nachbesserung entfallen kann).
Wenn ein Zahlenpaar '(1 . 1) beträgt, so bedeutet das, daß keine Korrektur erfolgt. Zahlen kleiner null ändern die Richtung. Es gibt jetzt auch die Möglichkeit den ersten zusätzlichen Balken durch Setzung von '(#f . #f) auszuschließen.
Ein vertikales auseinanderdriften der Teil-Beams habe ich nur noch dann gesehen, wenn die Richtung nicht stimmt. Die Korrektur erfolgte dann durch Setzung von '(-1 . 1) als "additional offset".
Den \layout-Block und die Möglichkeiten zur Einfärbung (im Code angezeigt durch: ;; <-- coloring) habe ich zur Konstruktionserleichterung benutzt und drin gelassen (ich finde sie recht hilfreich).
Ich habe noch eine (bislang unbeantwortete) Frage zu einem Teilaspekt des Problems auf der englischen Liste eingestellt. Sollte da etwas substantielles, rauskommen könnte ich das Ganze noch vereinfachen. Ansonsten glaube ich, daß es das Beste ist, was ich momentan erreichen kann.
Ansonsten habe ich ->hier (http://lists.gnu.org/archive/html/lilypond-user/2009-03/msg00620.html) noch eine ganz andere Herangehensweise gefunden:
\version "2.12.1"
% http://lists.gnu.org/archive/html/lilypond-user/2009-03/msg00620.html
\new Staff {
<< { \oneVoice \override Beam #'positions = #'(1 . 3.5)
c'8*1/2[ d' e' f' g' a' b' c'' d''] }
\new Voice { \oneVoice \override Beam #'positions = #'(1 . 1.2)
c'8*1/2[ d' e' f' g'] }
\new Voice { s4 \override Beam #'positions = #'(1.2 . 3.5) \stemUp
g'8*1/2[ a' b' c'' d''] }
>> }
Wenn man diesen Ansatz jedoch auf 32-tel erweitert muß man ebenfalls mit insgesamt zehn Variablen jonglieren (genau wie bei mir) und wird zusätzlich noch von Warnmeldungen im log überschwemmt. Außerdem finde ich den eigentlichen Code für die Musik noch unübersichtlicher. Aber entscheide selbst!
Gruß,
Harm
-
Lieber Harm,
Wo schon eine große Verbesserung! Mir gefällt es bei den "simplen" Beispielen, dass fast keine Änderungen nötig sind. Jetzt bin ich aber auf ein Problem gestoßen mit Beispiel E. Ich habe es geschafft, die Balken richtig zu ordnen, nur stimmt die Richtung nicht. Ich habe es auch nicht schaffen können es korrekt zu richten. Was mach ich da falsch?
\version "2.14.2"
#(set-global-staff-size 20)
\layout {
\context {
\Staff
\override Beam #'layer = #-4
%\override Beam #'color = #red
}
}
\markup \column { \bold \fill-line { "EXAMPLE" } \vspace #2 }
#(define ((grow-dir-var top y-offset corr-y slope-1 slope-2 slope-3) grob)
(cond ((= top 1) (and (display "\n ______________No Top wanted?________________________") #f))
((< top 1) (and (display "\n ______________No reachable Top!_____________________") #f))
((> top 1)
(if (ly:stencil? (ly:beam::print grob))
(let* ((beam (ly:beam::print grob))
(dir (ly:beam::calc-direction grob))
(beam-extent-X (ly:stencil-extent beam X))
(beam-length-x (interval-length beam-extent-X))
(beam-extent-Y (ly:stencil-extent beam Y))
(beam-length-y (interval-length beam-extent-Y))
(line-thickness (ly:output-def-lookup (ly:grob-layout grob) 'line-thickness))
(half-stem-thickness (/ (* 1.3 line-thickness) 2))
(beam-thickness (ly:grob-property grob 'beam-thickness))
(orig-slope (/ (- beam-length-y (+ (* 3 beam-thickness) 0.6)) beam-length-x))
(alpha (atan orig-slope))
(h-max (/ (+ (* 3 beam-thickness) 0.35) (cos alpha)))
;; markup-a is the longest beam
(markup-a (markup #:beam (- beam-length-x (* half-stem-thickness 1.25)) ;; length
(* (car slope-1) orig-slope) ;; slope
beam-thickness)) ;; thickness
;; markup-b is begin of the first additional beam
(y1 (- (/ (- beam-length-y (+ (* 3 beam-thickness) 0.6)) top) (/ h-max 2)))
(x1 (/ (- beam-length-x (* half-stem-thickness 1.25)) top))
(part-beam-1
(if (not (equal? (car slope-2) #f))
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.8)) ;; length
(* (car slope-2) dir (/ y1 x1)) ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-b (markup part-beam-1))
(first-part-beam-1 (grob-interpret-markup grob markup-b))
(first-part-beam-1-ext-y (ly:stencil-extent first-part-beam-1 Y))
(length-first-part-beam-1-y (interval-length first-part-beam-1-ext-y))
;; markup-bb is the end of the first additional beam
(y11 (- (- beam-length-y (+ (* 3 beam-thickness) 0.6)) y1 ))
(x11 (- beam-length-x x1))
(part-beam-11
(if (not (equal? (cdr slope-2) #f))
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.8)) ;; length
(* (cdr slope-2) dir (/ y11 x11)) ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-bb (markup part-beam-11))
;; markup-c is the begin of the second additional beam
(y2 (- (/ (- beam-length-y (+ (* 3 beam-thickness) 0.6)) top) h-max))
(x2 x1)
(part-beam-2
(if (not (equal? (car slope-3) #f))
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.8)) ;; length
(* (car slope-3) dir (/ y2 x2)) ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-c (markup part-beam-2))
(first-part-beam-2 (grob-interpret-markup grob markup-c))
(first-part-beam-2-ext-y (ly:stencil-extent first-part-beam-2 Y))
(length-first-part-beam-2-y (interval-length first-part-beam-2-ext-y))
;; markup-cc is the end of the second additional beam
(y22 (- (- beam-length-y (+ (* 3 beam-thickness) 0.6)) y2 ))
(x22 x11)
(part-beam-22
(if (not (equal? (cdr slope-3) #f))
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.8)) ;;length
(* (cdr slope-3) dir (/ y22 x22)) ;;slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-cc (markup part-beam-22))
) ;; end of defs in let*
(ly:stencil-translate-axis
(ly:stencil-add
;; first (long beam)
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-a)
(/ half-stem-thickness -2.7)
X)
;; parts of second beam
(ly:stencil-in-color
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-b)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-bb)
(* dir (car corr-y) (- length-first-part-beam-1-y beam-thickness))
Y)
0)
0 0 0) ;; <-- coloring
;; parts of third beam
(ly:stencil-in-color
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-c)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-cc)
(* dir (cdr corr-y) (* -1 (- length-first-part-beam-2-y beam-thickness)))
Y)
0)
0 0 0) ;; <-- coloring
) ;; end of stencil-add
(* dir y-offset (- beam-length-y (+ (* 3 beam-thickness) 1)))
Y)
) ;; end of let*
#f))))
%--------------------- Test ----------------------------------------------------
\relative c' {
\mark\markup { \with-color #red "A" }
\once \override Beam #'stencil = #(grow-dir-var 2 ; where to print the turn (2 is half-beam)
-1.5 ; Y-offset of the whole construct
'(-1 . 1) ; additional Y-offset
; '(<second part of the first added beam>
; .
; <second part of the second added beam>)
'(1 . 1) ; slope of the long beam (without) top
'(1 . 1) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(1 . 1)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
c32[ c c c c c c c]
\mark\markup { \with-color #red "B" }
\once \override Beam #'stencil = #(grow-dir-var 5 ; where to print the turn (2 is half-beam)
-1.5 ; Y-offset of the whole construct
'(-1 . 1) ; additional Y-offset
; '(<second part of the first added beam>
; .
; <second part of the second added beam>)
'(1 . 1) ; slope of the long beam (without) top
'(1 . 1) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(1 . 1)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
c32[ c c c c c c c]
\mark\markup { \with-color #red "C" }
\once \override Beam #'stencil = #(grow-dir-var 1.3 ; where to print the turn (2 is half-beam)
-1.5 ; Y-offset of the whole construct
'(-1 . 1) ; additional Y-offset
; '(<second part of the first added beam>
; .
; <second part of the second added beam>)
'(1 . 1) ; slope of the long beam (without) top
'(1 . 1) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(1 . 1)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
c32[ c c c c c c c]
}
\relative c' {
\mark\markup { \with-color #red "D" }
\once \override Beam #'stencil = #(grow-dir-var 2 ; where to print the turn (2 is half-beam)
-1.7 ; Y-offset of the whole construct
'(-1 . 1) ; additional Y-offset
; '(<second part of the first added beam>
; .
; <second part of the second added beam>)
'(1 . 1) ; slope of the long beam (without) top
'(1 . 1) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(1 . 1)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
g''32[ g g g g g g g]
\mark\markup { \with-color #red "E" }
\once \override Beam #'stencil = #(grow-dir-var 2 ; where to print the turn (2 is half-beam)
2 ; Y-offset of the whole construct
'(-1 . -1) ; additional Y-offset
; '(<second part of the first added beam>
; .
; <second part of the second added beam>)
'(1 . -1) ; slope of the long beam (without) top
'(-1 . -1) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(-1 . -1)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
c,,32[ e g b d f a c]
}
Was ich auch nicht verstehe:
Beam #'layer - Wenn ich das auskommentiere ändert sich (scheinbar nichts). Was hat es zu bedeuten?
Auch - das Y-Offset vom ganzen Konstrukt - Positive zahlen bewegen alles nach unten, negative nach oben. Klappt, aber warum nicht umgekehrt?
Grüße
kil
-
Hallo kil,
heute vormittag habe ich kaum Zeit, deshalb nur in aller Kürze: Meine Anfrage auf der englischen Liste führte tatsächlich zu einer wertvollen Erkenntnis.
In der Folge habe ich die notwendigen Variablen reduzieren können, y-offset konnte ich eliminieren (corr-y und slope-1 auch), deshalb gehe ich nicht weiter darauf ein.
Ich hatte noch keine Gelegenheit mich darum zu kümmern, ob es möglich ist die Definition für die zusätzlichen Balken auch noch zu verbessern. Genau dort liegt nämlich das Problem welches Du schilderst.
Nichtsdestotrotz kann man mit der Definition auf ihrem derzeitigen Stand zu einem befriedigenden Ergebnis kommen. (Die dazu nötigen Werte legen aber ebenfalls die Vermutung nahe, daß irgenwas noch nicht ganz in Ordnung ist.) Dein Beispiel ist bei Buchstabe "J".
Ein Wort zu 'layer. Das layer-property bestimmt in welcher Reihenfolge "gedruckt" wird. Wenn ich \override Beam #'layer = #-4 einstelle, dann wird der Balken (normalerweise) zuerst gedruckt. Sichtbar ist ein Effekt nur dann, wenn man den Balken einfärbt. Ich benutze es, um zu kontrollieren wie tief die Stems in den Beam hineinragen. Im Code unten habe ich per layout die Balkenfarbe (für den langen Balken) gelb eingestellt, sodaß Du den Effekt sehen können müßtest. Das kannst Du natürlich problemlos wieder rückgämgig machen. Die zusätzlichen Balken kann man auch einzeln einfärben (wenn auch an anderer Stelle im Code). Wie schon gesagt das Ganze dient der Kontrolle, nicht der Konstruktion.
\version "2.14.2"
#(set-global-staff-size 20)
\layout {
\context {
\Staff
\override Beam #'layer = #-4
\override Beam #'color = #yellow
}
}
\markup \column { \bold \fill-line { "EXAMPLE" } \vspace #2 }
#(define ((grow-dir-var top slope-2 slope-3) grob)
(cond ((= top 1) (and (display "\n ______________No Top wanted?________________________") #f))
((< top 1) (and (display "\n ______________No reachable Top!_____________________") #f))
((> top 1)
(if (ly:stencil? (ly:beam::print grob))
(let* ((beam (ly:beam::print grob))
(dir (ly:beam::calc-direction grob))
(beam-extent-X (ly:stencil-extent beam X))
(beam-length-x (interval-length beam-extent-X))
(beam-extent-Y (ly:stencil-extent beam Y))
(beam-length-y (interval-length beam-extent-Y))
(line-thickness (ly:output-def-lookup (ly:grob-layout grob) 'line-thickness))
(half-stem-thickness (/ (* 1.3 line-thickness) 2))
(beam-thickness (ly:grob-property grob 'beam-thickness))
(beam-positions (ly:grob-property grob 'positions))
(beam-slant (if (>= (car beam-positions) (cdr beam-positions)) -1 1))
(orig-slope (* beam-slant (/ (- beam-length-y (+ (* 3 beam-thickness) 0.6)) beam-length-x)))
(alpha (atan orig-slope))
(h-max (/ (+ (* 3 beam-thickness) 0.35) (cos alpha)))
;; markup-a is the longest beam
(markup-a (markup #:beam (- beam-length-x (* half-stem-thickness 1.25)) ;; length
orig-slope ;; slope
beam-thickness)) ;; thickness
;; markup-b is begin of the first additional beam
(y1 (- (/ (- beam-length-y (+ (* 3 beam-thickness) 0.6)) top) (/ h-max 2)))
(x1 (/ (- beam-length-x (* half-stem-thickness 1.25)) top))
(part-beam-1
(if (not (equal? (car slope-2) #f))
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.8)) ;; length
;(if (and (> dir 0) (> beam-slant 0))
;(/ y1 x1)
(* (car slope-2) dir (/ y1 x1))
;) ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-b (markup part-beam-1))
(first-part-beam-1 (grob-interpret-markup grob markup-b))
(first-part-beam-1-ext-y (ly:stencil-extent first-part-beam-1 Y))
(length-first-part-beam-1-y (interval-length first-part-beam-1-ext-y))
;; markup-bb is the end of the first additional beam
(y11 (- (- beam-length-y (+ (* 3 beam-thickness) 0.6)) y1 ))
(x11 (- beam-length-x x1))
(part-beam-11
(if (not (equal? (cdr slope-2) #f))
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.8)) ;; length
(* (cdr slope-2) dir (/ y11 x11)) ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-bb (markup part-beam-11))
;; markup-c is the begin of the second additional beam
(y2 (- (/ (- beam-length-y (+ (* 3 beam-thickness) 0.6)) top) h-max))
(x2 x1)
(part-beam-2
(if (not (equal? (car slope-3) #f))
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.8)) ;; length
(* (car slope-3) dir (/ y2 x2)) ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-c (markup part-beam-2))
(first-part-beam-2 (grob-interpret-markup grob markup-c))
(first-part-beam-2-ext-y (ly:stencil-extent first-part-beam-2 Y))
(length-first-part-beam-2-y (interval-length first-part-beam-2-ext-y))
;; markup-cc is the end of the second additional beam
(y22 (- (- beam-length-y (+ (* 3 beam-thickness) 0.6)) y2 ))
(x22 x11)
(part-beam-22
(if (not (equal? (cdr slope-3) #f))
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.8)) ;;length
(* (cdr slope-3) dir (/ y22 x22)) ;;slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-cc (markup part-beam-22))
) ;; end of defs in let*
(ly:stencil-translate-axis
(ly:stencil-add
;; first (long beam)
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-a)
(/ half-stem-thickness -2.5)
X)
;; parts of second beam
(ly:stencil-in-color
(ly:stencil-combine-at-edge
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-b)
(/ half-stem-thickness -2.5) X)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-bb)
(cond ((> dir 0)
(* beam-slant (- length-first-part-beam-1-y beam-thickness)))
((and (< dir 0) (> beam-slant 0))
(* beam-slant (- length-first-part-beam-1-y beam-thickness)))
((and (< dir 0) (< beam-slant 0))
(- length-first-part-beam-1-y beam-thickness)))
Y)
0)
0 0 0) ;; <-- coloring
;; parts of third beam
(ly:stencil-in-color
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-c)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-cc)
(cond ((> dir 0)
(* -1 (- length-first-part-beam-2-y beam-thickness)))
((and (< dir 0) (> beam-slant 0))
(* beam-slant (* beam-slant (- length-first-part-beam-2-y beam-thickness))))
((and (< dir 0) (< beam-slant 0))
(* beam-slant (* beam-slant (- length-first-part-beam-2-y beam-thickness)))))
Y)
0)
0 0 0) ;; <-- coloring
) ;; end of stencil-add
(car beam-positions)
Y)
) ;; end of let*
#f))))
%--------------------- Test ----------------------------------------------------
\relative c' {
\mark\markup { \with-color #red "A" }
\once \override Beam #'stencil = #(grow-dir-var 2 ; where to print the turn (2 is half-beam)
'(1 . 1) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(1 . 1)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
c32[ d e f g a b c]
\mark\markup { \with-color #red "B" }
\once \override Beam #'stencil = #(grow-dir-var 1.4 ; where to print the turn (2 is half-beam)
'(1 . 1) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(1 . 1)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
c,32[ d e f g a b c]
\mark\markup { \with-color #red "C" }
\once \override Beam #'stencil = #(grow-dir-var 2 '(8 . 0.17) '(2.5 . 0.55))
a32[ g f e d c b a]
\mark\markup { \with-color #red "D" }
\once\override Beam #'stencil = #(grow-dir-var 3.5 '(1 . 1) '(1 . 1))
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-dir-var 3 ; where to print the turn (2 is half-beam)
'(1 . 0.85) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(1 . 0.9)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
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-dir-var 3 '(2.5 . 0.1) '(1.6 . 0.45))
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-dir-var 3 '(1.2 . 1.03) '(1 . 1))
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-dir-var 1.3 '(1 . 1) '(1 . 1))
c,32 [c' c' c,, c d e f g c e b' c'
]
}
\relative c' {
\mark\markup { \with-color #red "J" }
\once \override Beam #'stencil = #(grow-dir-var 2
'(-3.2 . -0.33) ; slope '(<first part of the first added beam>
; .
; <second part of the first added beam>)
'(42 . 0.05)) % slope '(<first part of the second added beam>
% .
% <second part of the second added beam>)
% to delete the first or second additional
% beam use '(#f . #f)
c32[ e g b d f a c]
}
Gruß,
Harm
-
oh wow es wird noch besser! Und ja, 42 als wert hätte ich nie gedacht! Aber es sieht wunderbar aus, und wird immer einfacher. Ich werde am Wochenende damit weiter spielen können..... dann habe ich bestimmt weitere fragen!
Gruß
kil
-
Hallo kil,
hier die nächste Fassung. Der Befehl sieht jetzt so aus:
\override Beam #'stencil = #(grow-dir-var 2 #t #t)
Kaum noch Variablen! ;D (ein erster Versuch)
Die verbliebene Zahl bestimmt die Position der Spitze (wie bisher). Wenn Du die anderen auf #f setzt werden die zusätzlichen Balken separat ausgeschlossen. (Dies sollte drin bleiben, denn man will ja vielleicht auch mal 16-tel mit diesem Befehl ansprechen können. Ebenso könnte man darüber nachdenken das Ganze auf 64-tel etc zu erweitern ... )
Die Balkendicke habe ich verringert. Einerseits um mich dem default für 'grow-direction anzupassen, andererseits war sie mir sowieso zu massiv für dieses Vorhaben. Was meinst Du?
Die Definition überlebt jetzt auch manuelles ändern mittels \stemUp bzw \stemDown, sowie Änderungen der global-staff-size (Bei 6400% Vergrößerung sind allerdings kleinste Verschiebungen erkennbar, die ich nicht weg bekomme, da ich nicht weiß woher sie kommen. Auch sind sie nicht überall gleich).
Wenn ich die Definition mit so wenig Variablen setze, muß sie aber bombensicher sein und darf nirgenwo krachen gehen. Es wäre also schön, wenn Du sie ausgiebig testen und die Beispiele, bei denen sie kaput geht, dann posten könntest.
\version "2.14.2"
#(set-global-staff-size 20)
\paper {
ragged-last = ##t
}
\markup \column { \bold \fill-line { "EXAMPLES" } \vspace #2 }
#(define ((grow-dir-var top beam-2 beam-3) grob)
(cond ((= top 1) (and (display "\n ______________No Top wanted?________________________") #f))
((< top 1) (and (display "\n ______________No reachable Top!_____________________") #f))
((> top 1)
(if (ly:stencil? (ly:beam::print grob))
(let* ((beam (ly:beam::print grob))
(dir (ly:beam::calc-direction grob))
(beam-extent-X (ly:stencil-extent beam X))
(beam-length-x (interval-length beam-extent-X))
(beam-extent-Y (ly:stencil-extent beam Y))
(beam-length-y (interval-length beam-extent-Y))
(line-thickness (ly:output-def-lookup (ly:grob-layout grob) 'line-thickness))
(half-stem-thickness (/ (* 1.3 line-thickness) 2))
;;(beam-thickness (ly:grob-property grob 'beam-thickness))
;;(orig-beams-at-stem-length-y (* (* 3 beam-thickness) 1.45))
(beam-thickness (* 0.8 (ly:grob-property grob 'beam-thickness)))
(orig-beams-at-stem-length-y (* (* 3 beam-thickness) 1.8))
(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-beams-at-stem-length-y) beam-length-x)))
(alpha (atan orig-slope))
(h-max (/ (+ (* 3 beam-thickness) 0.35) (cos alpha)))
;; markup-a is the longest beam
(markup-a (markup #:beam (- beam-length-x (* half-stem-thickness 1.25)) ;; length
orig-slope ;; slope
beam-thickness)) ;; thickness
;; markup-b is begin of the first additional beam
(y1 (- (/ (- beam-length-y orig-beams-at-stem-length-y) top) (/ h-max 2)))
(y1a (+ (/ (- beam-length-y orig-beams-at-stem-length-y) top) (/ h-max 2)))
(y1b (+ (/ (- beam-length-y (* 0.65 orig-beams-at-stem-length-y)) top) (/ h-max 2)))
(x1 (/ (- beam-length-x (* half-stem-thickness 1.25)) top))
(slope-part-beam-1 (cond ((and (> dir 0) (> beam-slant 0))
(/ y1 x1))
((and (> dir 0) (< beam-slant 0))
(* -1 (/ y1a x1)))
((and (> dir 0) (= beam-slant 0))
(* 1 (/ y1 x1)))
((and (< dir 0) (> beam-slant 0))
(/ y1a x1))
((and (< dir 0) (< beam-slant 0))
(* -1 (/ y1 x1)))
((and (< dir 0) (= beam-slant 0))
(* -1 (/ y1 x1)))))
(part-beam-1
(if (not (equal? beam-2 #f))
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.8)) ;; length
slope-part-beam-1 ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-b (markup part-beam-1))
(first-part-beam-1 (grob-interpret-markup grob markup-b))
(first-part-beam-1-ext-y (ly:stencil-extent first-part-beam-1 Y))
(length-first-part-beam-1-y (interval-length first-part-beam-1-ext-y))
;; markup-bb is the end of the first additional beam
(y11 (- (- beam-length-y (* 1.01 orig-beams-at-stem-length-y)) y1 ))
(y11a (- (- beam-length-y (* 1 orig-beams-at-stem-length-y)) y1a ))
(y11b (- (- beam-length-y (* 0.6 orig-beams-at-stem-length-y)) y1b ))
(x11 (- beam-length-x x1))
(slope-part-beam-11 (cond ((and (> dir 0) (> beam-slant 0))
(/ y11 x11))
((and (> dir 0) (< beam-slant 0))
(* -1 (/ y11a x11)))
((and (> dir 0) (= beam-slant 0))
(* 1 (/ y11 x11)))
((and (< dir 0) (> beam-slant 0))
(/ y11a x11))
((and (< dir 0) (< beam-slant 0))
(* -1 (/ y11 x11)))
((and (< dir 0) (= beam-slant 0))
(* -1 (/ y11 x11)))))
(part-beam-11
(if (not (equal? beam-2 #f))
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.8)) ;; length
slope-part-beam-11 ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-bb (markup part-beam-11))
;; markup-c is the begin of the second additional beam
(y2 (- (/ (- beam-length-y orig-beams-at-stem-length-y) top) h-max))
(y2a (+ (/ (- beam-length-y orig-beams-at-stem-length-y) top) h-max))
(y2b (+ (/ (- beam-length-y (* 0.65 orig-beams-at-stem-length-y)) top) h-max))
(x2 x1)
(slope-part-beam-2 (cond ((and (> dir 0) (>= beam-slant 0))
(/ y2 x2))
((and (> dir 0) (< beam-slant 0))
(* -1 (/ y2a x2)))
((and (< dir 0) (> beam-slant 0))
(/ y2a x2))
((and (< dir 0) (< beam-slant 0))
(* -1 (/ y2 x2)))
((and (< dir 0) (= beam-slant 0))
(* -1 (/ y2 x2)))))
(part-beam-2
(if (not (equal? beam-3 #f))
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.8)) ;; length
slope-part-beam-2 ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-c (markup part-beam-2))
(first-part-beam-2 (grob-interpret-markup grob markup-c))
(first-part-beam-2-ext-y (ly:stencil-extent first-part-beam-2 Y))
(length-first-part-beam-2-y (interval-length first-part-beam-2-ext-y))
;; markup-cc is the end of the second additional beam
(y22 (- (- beam-length-y (* 1.01 orig-beams-at-stem-length-y)) y2 ))
(y22a (- (- beam-length-y orig-beams-at-stem-length-y) y2a ))
(x22 x11)
(slope-part-beam-22 (cond ((and (> dir 0) (>= beam-slant 0))
(/ y22 x22))
((and (> dir 0) (< beam-slant 0))
(* -1 (/ y22a x22)))
((and (< dir 0) (> beam-slant 0))
(/ y22a x22))
((and (< dir 0) (<= beam-slant 0))
(* -1 (/ y22 x22)))))
(part-beam-22
(if (not (equal? beam-3 #f))
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.8)) ;;length
slope-part-beam-22 ;; slope
beam-thickness) ;; thickness
(markup #:null)))
(markup-cc (markup part-beam-22))
) ;; end of defs in let*
(ly:stencil-translate-axis
(ly:stencil-add
;; first (long beam)
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-a)
(/ half-stem-thickness -2.5)
X)
;; parts of second beam
(ly:stencil-combine-at-edge
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-b)
(/ half-stem-thickness -2.5) X)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-bb)
(cond ((and (> dir 0)(> beam-slant 0))
(if (and (>= slope-part-beam-1 0)(>= slope-part-beam-11 0))
(* 1 (- length-first-part-beam-1-y beam-thickness))
(* -1 (- length-first-part-beam-1-y beam-thickness))))
((and (> dir 0)(< beam-slant 0))
(* -1 (- length-first-part-beam-1-y beam-thickness)))
((and (> dir 0)(= beam-slant 0))
(* -1 (- length-first-part-beam-1-y beam-thickness)))
((and (< dir 0)(> beam-slant 0))
(- length-first-part-beam-1-y beam-thickness))
((and (< dir 0)(< beam-slant 0))
(if (and (<= slope-part-beam-1 0)(<= slope-part-beam-11 0))
(* -1 (- length-first-part-beam-1-y beam-thickness))
(* 1 (- length-first-part-beam-1-y beam-thickness))))
((and (< dir 0)(= beam-slant 0))
(- length-first-part-beam-1-y beam-thickness))
)
Y)
0)
;; parts of third beam
(ly:stencil-combine-at-edge
(grob-interpret-markup grob markup-c)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-cc)
(cond ((and (> dir 0)(> beam-slant 0))
(if (and (>= slope-part-beam-2 0)(>= slope-part-beam-22 0))
(- length-first-part-beam-2-y beam-thickness)
(* -1 (- length-first-part-beam-2-y beam-thickness))))
((and (> dir 0)(< beam-slant 0))
(* -1 (- length-first-part-beam-2-y beam-thickness)))
((and (> dir 0)(= beam-slant 0))
(* -1 (- length-first-part-beam-2-y beam-thickness)))
((and (< dir 0)(> beam-slant 0))
(* 1 (- length-first-part-beam-2-y beam-thickness)))
((and (< dir 0)(< beam-slant 0))
(if (and (<= slope-part-beam-2 0)(<= slope-part-beam-22 0))
(* -1 (- length-first-part-beam-2-y beam-thickness))
(- length-first-part-beam-2-y beam-thickness)))
((and (< dir 0)(= beam-slant 0))
(- length-first-part-beam-2-y beam-thickness)))
Y)
0)
) ;; end of stencil-add
(car beam-positions)
Y)
) ;; end of let*
#f))))
%--------------------- Test ----------------------------------------------------
\relative c' { %\stemDown
\mark\markup { \with-color #red "A" }
\once \override Beam #'stencil = #(grow-dir-var 2 #t #t)
c32[ d e f g a b c]
\mark\markup { \with-color #red "B" }
\once \override Beam #'stencil = #(grow-dir-var 1.4 #t #t)
c,32[ d e f g a b c]
\mark\markup { \with-color #red "C" }
\once \override Beam #'stencil = #(grow-dir-var 2 #t #t)
a32[ g f e d c b a]
\mark\markup { \with-color #red "D" }
\once\override Beam #'stencil = #(grow-dir-var 3.5 #t #t)
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-dir-var 3 #t #t)
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-dir-var 3 #t #t)
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-dir-var 3 #t #t)
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-dir-var 1.3 #t #t)
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-dir-var 2 #t #t)
c,,,32[ e g b d f a c]
\mark\markup { \with-color #red "K" }
\once\override Beam #'stencil = #(grow-dir-var 2 #t #t)
c,,32 [c' c' c' c']
\bar "" \break
\mark\markup { \with-color #red "L" }
\once \override Beam #'positions = #'(1 . 1)
%\once
\override Beam #'stencil = #(grow-dir-var 2 #t #t)
f,,,,,32 [ f''' f,,, f''' f,,, f''' f,,, 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
\override Beam #'stencil = #(grow-dir-var 2 #t #t)
\override Beam #'concaveness = #0
c,,32 [ g' d' a'
\change Staff = RH
e' b' fis' cis']
cis32 [fis, b, e,
\change Staff = LH
a, d, g, c, ]
}
>>
Viel Spaß erst mal,
Harm
P.S. Bei Buchstabe "L" habe ich es mit kneed-beams versucht. Da stehen um Moment noch ein paar Notenhäls über. Vielleicht weiß jemand wie man die kürzt. Ich muß jetzt ins Bett! ;)
-
Hallo kil,
hier die nächste Fassung (ich habe es in grow-beam-var umbenannt):
\version "2.14.2"
#(set-global-staff-size 18)
\paper {
ragged-last = ##t
}
\markup \column { \bold \fill-line { "EXAMPLES" } \vspace #2 }
xy = \once\override Stem #'french-beaming = ##t
#(define ((grow-beam-var top) grob)
(if (< (length (cdr (ly:grob-property (ly:grob-parent grob X) 'beaming))) 2)
(ly:beam::print grob)
(cond ((= top 1) (and (display "\n ________________No Top wanted?______________________") (ly:beam::print grob)))
((< top 1) (and (display "\n ________No reachable Top! Use top > 1_______________") (ly:beam::print grob)))
((> top 1)
(if (ly:stencil? (ly:beam::print grob))
(let* ((beam (ly:beam::print grob))
(dir (ly:beam::calc-direction grob))
(beam-extent-X (ly:stencil-extent beam X))
(beam-length-x (interval-length beam-extent-X))
(beam-extent-Y (ly:stencil-extent beam Y))
(beam-length-y (interval-length beam-extent-Y))
(line-thickness (ly:output-def-lookup (ly:grob-layout grob) 'line-thickness))
(half-stem-thickness (/ (* 1.3 line-thickness) 2))
(orig-beam-thickness (ly:grob-property grob 'beam-thickness))
;; Thanks to David Nalesnik
(beam-count (length (cdr (ly:grob-property (ly:grob-parent grob X) 'beaming)))) ;; the number of beams
(space-between-beams (* 0.44 (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))
; markup-a is the longest beam
(beam-thickness (* 0.8 (ly:grob-property grob 'beam-thickness)))
(h-max (- (/ orig-beam-length-at-stem (cos alpha)) (* 1.3 beam-thickness)))
(markup-a (markup #:beam (- beam-length-x (* half-stem-thickness 1.25))
orig-slope
beam-thickness))
; markup-b is begin of the first additional beam
(y1 (- (/ (- beam-length-y orig-beam-length-at-stem) top) (* dir beam-slant (* 1 (/ h-max (- beam-count 1))))))
(x1 (/ (- beam-length-x (* half-stem-thickness 1.25)) top))
(slope-part-beam-1 (cond ((and (> dir 0) (>= beam-slant 0))
(/ y1 x1))
((and (> dir 0) (< beam-slant 0))
(* -1 (/ y1 x1)))
((and (< dir 0) (> beam-slant 0))
(/ y1 x1))
((and (< dir 0) (<= beam-slant 0))
(* -1 (/ y1 x1)))))
(part-beam-1
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.6))
slope-part-beam-1
beam-thickness))
(markup-b (markup part-beam-1))
(first-part-beam-1 (grob-interpret-markup grob markup-b))
(first-part-beam-1-ext-y (ly:stencil-extent first-part-beam-1 Y))
(length-first-part-beam-1-y (interval-length first-part-beam-1-ext-y))
; markup-bb is the end of the first additional beam
(y11 (- (- beam-length-y orig-beam-length-at-stem) y1 ))
(x11 (- beam-length-x x1))
(slope-part-beam-11 (cond ((and (> dir 0) (>= beam-slant 0))
(/ y11 x11))
((and (> dir 0) (< beam-slant 0))
(* -1 (/ y11 x11)))
((and (< dir 0) (> beam-slant 0))
(/ y11 x11))
((and (< dir 0) (<= beam-slant 0))
(* -1 (/ y11 x11)))))
(part-beam-11
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.6))
slope-part-beam-11
beam-thickness))
(markup-bb (markup part-beam-11))
; markup-c is the begin of the second additional beam
(y2 (- (/ (- beam-length-y orig-beam-length-at-stem) top) (* dir beam-slant (* 2 (/ h-max (- beam-count 1))))))
(x2 x1)
(slope-part-beam-2 (cond ((and (> dir 0) (>= beam-slant 0))
(/ y2 x2))
((and (> dir 0) (< beam-slant 0))
(* -1 (/ y2 x2)))
((and (< dir 0) (> beam-slant 0))
(/ y2 x2))
((and (< dir 0) (<= beam-slant 0))
(* -1 (/ y2 x2)))))
(part-beam-2 (if (< beam-count 3)
(markup #:null)
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.6))
slope-part-beam-2
beam-thickness)
))
(markup-c (markup part-beam-2))
(first-part-beam-2 (grob-interpret-markup grob markup-c))
(first-part-beam-2-ext-y (ly:stencil-extent first-part-beam-2 Y))
(length-first-part-beam-2-y (interval-length first-part-beam-2-ext-y))
; markup-cc is the end of the second additional beam
(y22 (- (- beam-length-y orig-beam-length-at-stem) y2 ))
(x22 x11)
(slope-part-beam-22 (cond ((and (> dir 0) (>= beam-slant 0))
(/ y22 x22))
((and (> dir 0) (< beam-slant 0))
(* -1 (/ y22 x22)))
((and (< dir 0) (> beam-slant 0))
(/ y22 x22))
((and (< dir 0) (<= beam-slant 0))
(* -1 (/ y22 x22)))))
(part-beam-22 (if (< beam-count 3)
(markup #:null)
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.6))
slope-part-beam-22
beam-thickness)))
(markup-cc (markup part-beam-22))
; markup-d is the begin of the third additional beam
(y3 (- (/ (- beam-length-y orig-beam-length-at-stem) top) (* dir beam-slant (* 3 (/ h-max (- beam-count 1))))))
(x3 x1)
(slope-part-beam-3 (cond ((and (> dir 0) (>= beam-slant 0))
(/ y3 x3))
((and (> dir 0) (< beam-slant 0))
(* -1 (/ y3 x3)))
((and (< dir 0) (> beam-slant 0))
(/ y3 x3))
((and (< dir 0) (<= beam-slant 0))
(* -1 (/ y3 x3)))))
(part-beam-3 (if (< beam-count 4)
(markup #:null)
(markup #:beam (- (/ beam-length-x top) (* half-stem-thickness 0.6))
slope-part-beam-3
beam-thickness)))
(markup-d (markup part-beam-3))
(first-part-beam-3 (grob-interpret-markup grob markup-d))
(first-part-beam-3-ext-y (ly:stencil-extent first-part-beam-3 Y))
(length-first-part-beam-3-y (interval-length first-part-beam-3-ext-y))
; markup-dd is the end of the third additional beam
(y33 (- (- beam-length-y orig-beam-length-at-stem) y3 ))
(x33 x11)
(slope-part-beam-33 (cond ((and (> dir 0) (>= beam-slant 0))
(/ y33 x33))
((and (> dir 0) (< beam-slant 0))
(* -1 (/ y33 x33)))
((and (< dir 0) (> beam-slant 0))
(/ y33 x33))
((and (< dir 0) (<= beam-slant 0))
(* -1 (/ y33 x33)))))
(part-beam-33 (if (< beam-count 4)
(markup #:null)
(markup #:beam (- (- beam-length-x (/ beam-length-x top)) (* half-stem-thickness 0.6))
slope-part-beam-33
beam-thickness)))
(markup-dd (markup part-beam-33))
) ;; end of defs in let*
(if (> beam-count 4)
(and (display "\n ____________Not defined for this beam-count____________") beam)
(ly:stencil-translate-axis
(ly:stencil-add
;; first (long beam)
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-a)
(/ half-stem-thickness -2.5)
X)
;; parts of second beam
(ly:stencil-combine-at-edge
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-b)
(/ half-stem-thickness -2.5) X)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-bb)
(cond ((and (> dir 0)(> beam-slant 0))
(if (and (>= slope-part-beam-1 0)(>= slope-part-beam-11 0))
(- length-first-part-beam-1-y beam-thickness)
(* -1 (- length-first-part-beam-1-y beam-thickness))))
((and (> dir 0)(< beam-slant 0))
(* -1 (- length-first-part-beam-1-y beam-thickness)))
((and (> dir 0)(= beam-slant 0))
(* -1 (- length-first-part-beam-1-y beam-thickness)))
((and (< dir 0)(> beam-slant 0))
(- length-first-part-beam-1-y beam-thickness))
((and (< dir 0)(< beam-slant 0))
(if (and (<= slope-part-beam-1 0)(<= slope-part-beam-11 0))
(* -1 (- length-first-part-beam-1-y beam-thickness))
(- length-first-part-beam-1-y beam-thickness)))
((and (< dir 0)(= beam-slant 0))
(- length-first-part-beam-1-y beam-thickness))
)
Y)
0)
;; parts of third beam
(ly:stencil-combine-at-edge
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-c)
(/ half-stem-thickness -2.5) X)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-cc)
(cond ((and (> dir 0)(> beam-slant 0))
(if (and (>= slope-part-beam-2 0)(>= slope-part-beam-22 0))
(- length-first-part-beam-2-y beam-thickness)
(* -1 (- length-first-part-beam-2-y beam-thickness))))
((and (> dir 0)(< beam-slant 0))
(* -1 (- length-first-part-beam-2-y beam-thickness)))
((and (> dir 0)(= beam-slant 0))
(* -1 (- length-first-part-beam-2-y beam-thickness)))
((and (< dir 0)(> beam-slant 0))
(- length-first-part-beam-2-y beam-thickness))
((and (< dir 0)(< beam-slant 0))
(if (and (<= slope-part-beam-2 0)(<= slope-part-beam-22 0))
(* -1 (- length-first-part-beam-2-y beam-thickness))
(- length-first-part-beam-2-y beam-thickness)))
((and (< dir 0)(= beam-slant 0))
(- length-first-part-beam-2-y beam-thickness)))
Y)
0)
;; parts of fourth beam
(ly:stencil-combine-at-edge
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-d)
(/ half-stem-thickness -2.5) X)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-dd)
(cond ((and (> dir 0)(> beam-slant 0))
(if (and (>= slope-part-beam-3 0)(>= slope-part-beam-33 0))
(- length-first-part-beam-3-y beam-thickness)
(* -1 (- length-first-part-beam-3-y beam-thickness))))
((and (> dir 0)(< beam-slant 0))
(* -1 (- length-first-part-beam-3-y beam-thickness)))
((and (> dir 0)(= beam-slant 0))
(* -1 (- length-first-part-beam-3-y beam-thickness)))
((and (< dir 0)(> beam-slant 0))
(* 1 (- length-first-part-beam-3-y beam-thickness)))
((and (< dir 0)(< beam-slant 0))
(if (and (<= slope-part-beam-3 0)(<= slope-part-beam-33 0))
(* -1 (- length-first-part-beam-3-y beam-thickness))
(- length-first-part-beam-3-y beam-thickness)))
((and (< dir 0)(= beam-slant 0))
(- length-first-part-beam-3-y beam-thickness)))
Y)
0);; end of parts of fourth beam
) ;; end of stencil-add
(car beam-positions)
Y)
)
) ;; end of let*
#f)))))
%--------------------- Test ----------------------------------------------------
\relative c' {
\mark\markup { \with-color #red "A" }
\once \override Beam #'stencil = #(grow-beam-var 2)
c32[ d e f g a b c]
\mark\markup { \with-color #red "B" }
\once \override Beam #'stencil = #(grow-beam-var 1.4)
c,32[ d e f g a b c]
\mark\markup { \with-color #red "C" }
\once \override Beam #'stencil = #(grow-beam-var 2)
a32[ g f e d c b a]
\mark\markup { \with-color #red "D" }
\once\override Beam #'stencil = #(grow-beam-var 3.7)
c,64 [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 3)
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 3)
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 3)
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 1.35)
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 2.2)
c,,,32[ e g b d f a c]
\mark\markup { \with-color #red "K" }
\once\override Beam #'stencil = #(grow-beam-var 2)
c,,32 [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 2)
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 1.88)
\override Beam #'concaveness = #0
c,,32 [ g'
\change Staff = RH
d' a' e' b' fis' cis']
\once\override Beam #'stencil = #(grow-beam-var 2.4)
cis32 [fis, b, e, a, d,
\change Staff = LH
g, c, ]
}
>>
one =
\relative c' {
\once\override Beam #'stencil = #(grow-beam-var 1.37)
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 3.3)
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 2)
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
}
Die Funktion ist jetzt bis auf 64-tel erweitert. Das Auslesen des Notenwertes erfolgt automatisch und damit auch die Anzahl der Balken die benötigt werden. Größere Notenwerten bleiben unbehelligt. Bei noch kleineren Notenwerten wird der default-beam ausgegeben und es erfolgt eine Warnung im log.
Es gibt immer noch kleine Verschiebungen bei massiver Änderung der global-staff-size. Das liegt am ausgelesenen gap-Wert (Zeile 31). Ich weiß zwar jetzt woher es kommt, aber nicht wie man es abstellt.:(
Die überstehenden stems bei kneed-beams habe ich mittels \once\override Stem #'french-beaming = ##t provisorisch gefixt. Das funktioniert aber nicht bei den äußeren stems unter einem beam. Insofern sind in diesem Punkt Probleme absehbar.
Ansonsten träume ich davon das Ganze rekursiv zu definieren. Dann könnte man eine wirklich allgemein gültige Definition erstellen.
Hast Du eigentlich mittlerweile Beispiele gefunden, mit denen die Funktion krachen geht?
Gruß,
Harm
-
Lieber Harm,
Unglaublich toll! Ich habe versucht, konnte aber das Konstrukt nicht knacken! Hut ab!
Eine Sache finde ich aber immer noch verwirrend bzw. nicht intuitiv, und zwar die einzige übrig gebliebene Variabel. 2 ist mittig, das ist klar, aber 1 als Wert geht nicht. 3, 4, 5, usw geht. Also ich verstehe wie ich die Werte eingeben muss (zB 1.01 geht), finde es aber ein bisschen komisch wie die Werte funktionieren. Das nur als neben Kommentar.
Was ich dabei toll fand was nicht mit dem Beam zu tun hat, war deine "expr" Variabel. Ich habe sowas immer zweistimmig gebaut, hatte keine Ahnung, dass man es auch so hinkriegt! Danke dafür!
Und nun, weil ich es nicht persönlich vor dir machen kann....
http://www.youtube.com/watch?v=Vh78T--ZUxY (http://www.youtube.com/watch?v=Vh78T--ZUxY)
-
Hi kil,
Und nun, weil ich es nicht persönlich vor dir machen kann....
http://www.youtube.com/watch?v=Vh78T--ZUxY
ROFLMAO
Eine Sache finde ich aber immer noch verwirrend bzw. nicht intuitiv, und zwar die einzige übrig gebliebene Variabel.
Das seh' ich auch so. Ich habe mir diese Problem noch aufgehoben, denn es hat keine direkten Auswirkungen auf die Funktionalität der Definition. Die Schwierigkeit liegt darin, daß "top" ein Divisor ist. Und die graphische Darstellung von 1/x ist nun mal eine Hyperbel und keine einfache lineare Beziehung. Hinzu kommt, daß ich unsicher bin wie eine benutzerfreundliche Lösung aussehen sollte/könnte.
Aber ich denke weiter drüber nach.
Gruß,
Harm
-
Hallo,
ich hoffe, ich darf dies mal an dieser Stelle fragen.
Sind diese Noten für eine E-Gitarre? Wie darf man sich dies musikalisch vorstellen? Ist das eine Art verzerren mit dem Jammerhaken?
Herzliche Grüße
matrices
-
Das seh' ich auch so. Ich habe mir diese Problem noch aufgehoben, denn es hat keine direkten Auswirkungen auf die Funktionalität der Definition. Die Schwierigkeit liegt darin, daß "top" ein Divisor ist. Und die graphische Darstellung von 1/x ist nun mal eine Hyperbel und keine einfache lineare Beziehung. Hinzu kommt, daß ich unsicher bin wie eine benutzerfreundliche Lösung aussehen sollte/könnte.
Aber ich denke weiter drüber nach.
Naja es ist eher so ein Kleinigkeit. Aber jetzt endlich verstehe ich was offensichtlich zu sehen sein sollte, nämlich das 1/x !!! Natürlich!
@matrices
die Notation bezeichnet eine allmählich accelerando bzw. ritardando. Lilypond hat beide Optionen als default, aber nicht beide kombiniert. Das sieht man ab und zu in der neuen Musik, und ist für jeden Instrument zu gebrauchen.
Gruß
kil
-
Hallo kil,
mit Hilfe von David Nalesnik von der englischen Liste, ist es mir gelungen die noch verbliebenen Verschiebungen bei Änderungen der global-staff-size in den Griff zu bekommen.
Darüberhinaus konnte ich die Eingabe deutlich benutzerfreundlicher gestalten (war sogar leichter als gedacht). Es sind jetzt alle Werte zwischen 0 und 1 möglich. (Bei exakt 0 oder 1 gibts eine Warnmeldung). Die Eingabe wird linear verarbeitet, d.h. 0.2 entspricht einem fünftel Beam-Länge, 0.4 zwei fünftel etc).
Ich habe die Funktion jetzt auch auf der englischen Liste (http://old.nabble.com/Making-feathered-beams-more-variable-td32705102.html) gepostet, in der Hoffnung, daß es noch substantielle Rückmeldungen gibt auf deren Grundlage ich das Ganze noch weiter verbessern kann. Und vielleicht gelingt es ja jemandem die Funktion rekursiv zu definieren, um dann eine wirklich verallgemeinerte Fassung zu haben.
Ansonsten ist hier dann die neueste Fassung:
\version "2.14.2"
#(set-global-staff-size 18)
\markup \column { \bold \fill-line { "EXAMPLES" } \vspace #2 }
xy = \once\override Stem #'french-beaming = ##t
#(define ((grow-beam-var top) grob)
(if (< (length (cdr (ly:grob-property (ly:grob-parent grob X) 'beaming))) 2)
(ly:beam::print grob)
(cond ((= top 1) (and (display "\n _______________Use: \\override Beam #'grow-direction = #'RIGHT__________________")
(ly:beam::print grob)))
((= top 0) (and (display "\n _______________Use: \\override Beam #'grow-direction = #'LEFT___________________")
(ly:beam::print grob)))
((or (< top 0)(> top 1))(and (display "\n _______________No reachable top__________________")
(ly:beam::print grob)))
((and (> top 0) (< top 1))
(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)))
; markup-a is the longest beam
(markup-a (markup #:beam beam-length-x
orig-slope
beam-thickness))
; markup-b is begin of the first additional beam
(y1 (- (* (- beam-length-y orig-beam-length-at-stem) top) (* dir beam-slant (* 1 (/ h-max (- beam-count 1))))))
(x1 (* beam-length-x top))
(slope-part-beam-1 (cond ((or (and (> dir 0) (> beam-slant 0)) (and (< dir 0) (> beam-slant 0)))
(/ y1 x1))
((or (and (> dir 0) (< beam-slant 0)) (and (< dir 0) (< beam-slant 0)))
(* -1 (/ y1 x1)))))
(part-beam-1
(markup #:beam (* beam-length-x top)
slope-part-beam-1
beam-thickness))
(markup-b (markup part-beam-1))
(first-part-beam-1 (grob-interpret-markup grob markup-b))
(first-part-beam-1-ext-y (ly:stencil-extent first-part-beam-1 Y))
(length-first-part-beam-1-y (interval-length first-part-beam-1-ext-y))
; markup-bb is the end of the first additional beam
(y11 (- (- beam-length-y orig-beam-length-at-stem) y1 ))
(x11 (- beam-length-x x1))
(slope-part-beam-11 (cond ((or (and (> dir 0) (> beam-slant 0)) (and (< dir 0) (> beam-slant 0)))
(/ y11 x11))
((or (and (> dir 0) (< beam-slant 0)) (and (< dir 0) (< beam-slant 0)))
(* -1 (/ y11 x11)))))
(part-beam-11
(markup #:beam (- beam-length-x (* beam-length-x top))
slope-part-beam-11
beam-thickness))
(markup-bb (markup part-beam-11))
; markup-c is the begin of the second additional beam
(y2 (- (* (- beam-length-y orig-beam-length-at-stem) top) (* dir beam-slant (* 2 (/ h-max (- beam-count 1))))))
(x2 x1)
(slope-part-beam-2 (cond ((or (and (> dir 0) (> beam-slant 0)) (and (< dir 0) (> beam-slant 0)))
(/ y2 x2))
((or (and (> dir 0) (< beam-slant 0)) (and (< dir 0) (< beam-slant 0)))
(* -1 (/ y2 x2)))))
(part-beam-2 (if (< beam-count 3)
(markup #:null)
(markup #:beam (* beam-length-x top)
slope-part-beam-2
beam-thickness)
))
(markup-c (markup part-beam-2))
(first-part-beam-2 (grob-interpret-markup grob markup-c))
(first-part-beam-2-ext-y (ly:stencil-extent first-part-beam-2 Y))
(length-first-part-beam-2-y (interval-length first-part-beam-2-ext-y))
; markup-cc is the end of the second additional beam
(y22 (- (- beam-length-y orig-beam-length-at-stem) y2 ))
(x22 x11)
(slope-part-beam-22 (cond ((or (and (> dir 0) (> beam-slant 0)) (and (< dir 0) (> beam-slant 0)))
(/ y22 x22))
((or (and (> dir 0) (< beam-slant 0)) (and (< dir 0) (< beam-slant 0)))
(* -1 (/ y22 x22)))))
(part-beam-22 (if (< beam-count 3)
(markup #:null)
(markup #:beam (- beam-length-x (* beam-length-x top))
slope-part-beam-22
beam-thickness)))
(markup-cc (markup part-beam-22))
; markup-d is the begin of the third additional beam
(y3 (- (* (- beam-length-y orig-beam-length-at-stem) top) (* dir beam-slant (* 3 (/ h-max (- beam-count 1))))))
(x3 x1)
(slope-part-beam-3 (cond ((or (and (> dir 0) (> beam-slant 0)) (and (< dir 0) (> beam-slant 0)))
(/ y3 x3))
((or (and (> dir 0) (< beam-slant 0)) (and (< dir 0) (< beam-slant 0)))
(* -1 (/ y3 x3)))))
(part-beam-3 (if (< beam-count 4)
(markup #:null)
(markup #:beam (* beam-length-x top)
slope-part-beam-3
beam-thickness)))
(markup-d (markup part-beam-3))
(first-part-beam-3 (grob-interpret-markup grob markup-d))
(first-part-beam-3-ext-y (ly:stencil-extent first-part-beam-3 Y))
(length-first-part-beam-3-y (interval-length first-part-beam-3-ext-y))
; markup-dd is the end of the third additional beam
(y33 (- (- beam-length-y orig-beam-length-at-stem) y3 ))
(x33 x11)
(slope-part-beam-33 (cond ((or (and (> dir 0) (> beam-slant 0)) (and (< dir 0) (> beam-slant 0)))
(/ y33 x33))
((or (and (> dir 0) (< beam-slant 0)) (and (< dir 0) (< beam-slant 0)))
(* -1 (/ y33 x33)))))
(part-beam-33 (if (< beam-count 4)
(markup #:null)
(markup #:beam (- beam-length-x (* beam-length-x top))
slope-part-beam-33
beam-thickness)))
(markup-dd (markup part-beam-33))
) ;; end of defs in let*
(if (> beam-count 4)
(and (display "\n ____________Not defined for this beam-count____________") beam)
(ly:stencil-translate-axis
(ly:stencil-add
;; first (long beam)
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-a)
-0.025 X)
;; parts of second beam
(ly:stencil-combine-at-edge
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-b)
-0.025 X)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-bb)
(cond ((and (> dir 0)(> beam-slant 0))
(if (and (>= slope-part-beam-1 0)(>= slope-part-beam-11 0))
(- length-first-part-beam-1-y beam-thickness)
(* -1 (- length-first-part-beam-1-y beam-thickness))))
((and (> dir 0)(< beam-slant 0))
(* -1 (- length-first-part-beam-1-y beam-thickness)))
((and (< dir 0)(> beam-slant 0))
(- length-first-part-beam-1-y beam-thickness))
((and (< dir 0)(< beam-slant 0))
(if (and (<= slope-part-beam-1 0)(<= slope-part-beam-11 0))
(* -1 (- length-first-part-beam-1-y beam-thickness))
(- length-first-part-beam-1-y beam-thickness)))
)
Y)
0)
;; parts of third beam
(ly:stencil-combine-at-edge
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-c)
-0.025 X)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-cc)
(cond ((and (> dir 0)(> beam-slant 0))
(if (and (>= slope-part-beam-2 0)(>= slope-part-beam-22 0))
(- length-first-part-beam-2-y beam-thickness)
(* -1 (- length-first-part-beam-2-y beam-thickness))))
((and (> dir 0)(< beam-slant 0))
(* -1 (- length-first-part-beam-2-y beam-thickness)))
((and (< dir 0)(> beam-slant 0))
(- length-first-part-beam-2-y beam-thickness))
((and (< dir 0)(< beam-slant 0))
(if (and (<= slope-part-beam-2 0)(<= slope-part-beam-22 0))
(* -1 (- length-first-part-beam-2-y beam-thickness))
(- length-first-part-beam-2-y beam-thickness)))
)
Y)
0)
;; parts of fourth beam
(ly:stencil-combine-at-edge
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-d)
-0.025 X)
X RIGHT
(ly:stencil-translate-axis
(grob-interpret-markup grob markup-dd)
(cond ((and (> dir 0)(> beam-slant 0))
(if (and (>= slope-part-beam-3 0)(>= slope-part-beam-33 0))
(- length-first-part-beam-3-y beam-thickness)
(* -1 (- length-first-part-beam-3-y beam-thickness))))
((and (> dir 0)(< beam-slant 0))
(* -1 (- length-first-part-beam-3-y beam-thickness)))
((and (< dir 0)(> beam-slant 0))
(- length-first-part-beam-3-y beam-thickness))
((and (< dir 0)(< beam-slant 0))
(if (and (<= slope-part-beam-3 0)(<= slope-part-beam-33 0))
(* -1 (- length-first-part-beam-3-y beam-thickness))
(- length-first-part-beam-3-y beam-thickness)))
)
Y)
0);; end of parts of fourth beam
) ;; end of stencil-add
(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)
c32[ d e f g a b c]
\mark\markup { \with-color #red "B" }
\once \override Beam #'stencil = #(grow-beam-var 0.71)
c,32[ d e f g a b c]
\mark\markup { \with-color #red "C" }
\once \override Beam #'stencil = #(grow-beam-var 0.5)
a64[ g f e d c b a]
\mark\markup { \with-color #red "D" }
\once\override Beam #'stencil = #(grow-beam-var 0.265)
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 0.333)
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 0.335)
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 0.3333)
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 0.735)
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 0.59)
c,,,32[ e g b d f a c]
\mark\markup { \with-color #red "K" }
\once\override Beam #'stencil = #(grow-beam-var 0.5)
c,,32 [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 0.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 0.53)
\override Beam #'concaveness = #0
c,,32 [ g'
\change Staff = RH
d' a' e' b' fis' cis']
\once\override Beam #'stencil = #(grow-beam-var 0.42)
cis32 [fis, b, e, a, d,
\change Staff = LH
g, c, ]
}
>>
one =
\relative c' {
\once\override Beam #'stencil = #(grow-beam-var 0.8)
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 0.305)
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 0.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
}
Gruß,
Harm
P.S. Getestet habe ich mit "2.14.2" und "2.15.13"
Im Anhang noch eine Fassung, die auch mit "2.12.3" funktionieren sollte.
-
Harm du bist einfach genial! Ich liebe es! Wenn du mal in Berlin bist lade ich dich auf ein Kaffee ein :)
-
Hallo kil,
in Zusammenarbeit mit David sind noch eine Reihe von Änderungen und Weiterungen zu vermelden:
Allgemeingültigkeit
David ist es gelungen die Funktion rekursiv zu definieren. Sie ist jetzt also wirklich allgemeingültig. (Du kannst jetzt auch 1024-tel benutzen, wenn Du willst.)
Eingabe "anhand der Notenhälse"
Auf seine Anregung hin habe ich die Eingabe noch mal verändert. Sie orientiert sich jetzt an den Notenhälsen, wobei zu beachten ist, daß der erste Notenhals die Nummer 0 trägt. (grow-dir-var 5) setzt die Spitze jetzt also genau auf den sechsten Notenhals. (grow-dir-var 0) führt zum default-Befehl \override Beam #'grow-direction = #LEFT. Werte größer als die maximale Anzahl der Notenhälse unter dem Balken führen zu \override Beam #'grow-direction = #RIGHT. Du kannst aber auch etwas wie (grow-dir-var 3.5) eingeben, dann wird die Spitze zwischen dem vierten und fünften Notenhals zentriert. Andere Komma-Zahlen sind auch möglich.
Kneed-Beams
Für kneed-Beams gibts noch ein paar Besonderheiten.
Orientierung der Spitze
Bei Buchstabe "O" konnte ich mich nicht entscheiden, ob die Spitze nach oben oder nach unten zeigen sollte. Insofern habe ich ein feature eingebaut mit dem Du die Spitze umdrehen kannst. Es funktioniert aber nur für kneed-Beams und(!) wenn der Balken horizontal ist (um sicher zu gehen, daß er horizontal ist kann man \once \override Beam #'positions = #'(0 . 0) benutzen, wobei man '(0 . 0) evtl noch anpassen muß. Natürlich müssen die beiden Zahlen gleich sein, denn sonst ist der Balken ja nicht mehr horizontal: '(0.5 . 0.5) funktioniert also, '(0 . 1) natürlich nicht).
Um die Spitze umdrehen zu können, gebe negative Zahlen ein. (Wenn es sich nicht um kneed-Beams handelt und(!) der Balken nicht horizontal ist, werden die negativen Zahlen in positive umgedeutet).
Man könnte dieses feature auch verallgemeinern. Das wäre allerdings noch sehr viel Arbeit. Da ich glaube, daß die (potenzielle) Verallgemeinerung seltenst benutzt werden wird, möchte ich mich nur dann damit beschäftigen, wenn gesteigerter Bedarf angemeldet wird. ;)
Überstehende Notenhälse
Es kann bei kneed-Beams vorkommen, daß es überstehende Notenhälse gibt (siehe Buchstabe "R").
Die äußeren, den Beam begrenzenden Notenhälse sind ein Sonderfall. Die inneren Notenhälse kannst Du im Einzelfall mit xy = \once\override Stem #'french-beaming = ##t verkürzen (siehe Code bei Buchstabe "Q"). Bei den äußeren Notenhälsen ist der erste nie ein Problem. Der letzte ist dann ein Problem, wenn er in eine andere Richtung zeigt als der erste. Um diesen Notenhals zu verkürzen hat sich David etwas einfallen lassen, was ich dann in eine Funktion verwandelt habe:
#(define ((stem-length y) grob)
(ly:grob-set-property! grob 'length y)
(ly:stem::print grob))
xyOut =
#(define-music-function (parser location y-length)(number?)
#{
\once \override Stem #'stencil = #(stem-length $y-length)
#})
Anwendung z.B. bei Buchstabe "Q".
Leider gibt es zwei Einschränkungen mit dieser Funktion: Sie funktioniert nicht mit "2.14.2" sondern erst mit höheren Versionen. Ich habe es mit "2.15.13" getestet. Darüberhinaus funktioniert sie nicht in Verbindung mit \change Staff.
Vielleicht fällt uns ja noch etwas besseres ein.
\featherDurations
Zusätzlich habe ich noch versucht das Ganze mit \featherDurations #(ly:make-moment 1 2) etc zu verbinden (Buchstabe "P"). Allerdings unterliegt diese Funktion so starken Beschränkungen, daß sie häufig nicht arbeitet.-> NR 1.2.4 Balken-Gespreizte Balken (http://lilypond.org/doc/v2.14/Documentation/notation-big-page.de.html#feathered-beams):
Bekannte Probleme und Warnungen
Der \featherDurations-Befehl funktioniert nur mit kurzen Notenabschnitten, und wenn die Zahlen in den Brüchen klein sind.
Aber ich denke weiter drüber nach.
Code
\version "2.14.2"
\pointAndClickOff
#(set-global-staff-size 18)
\paper { tagline = ##f }
\markup \column { \bold \fill-line { "EXAMPLES" } \vspace #2 }
xy = \once\override Stem #'french-beaming = ##t
% xyOut needs "2.15.13"
#(define ((stem-length y) grob)
(ly:grob-set-property! grob 'length y)
(ly:stem::print grob))
xyOut =
#(define-music-function (parser location y-length)(number?)
#{
\once \override Stem #'stencil = #(stem-length $y-length)
#})
#(define ((grow-beam-var number) grob)
;; Thanks to David Nalesnik
(cond
((< (length (cdr (ly:grob-property (ly:grob-parent grob X) 'beaming))) 2)
(ly:beam::print grob))
((= number 0)
(begin
(ly:grob-set-property! grob 'grow-direction LEFT)
(ly:beam::print grob)))
((>= number (1- (ly:grob-array-length (ly:grob-object grob 'stems))))
(begin
(ly:grob-set-property! grob 'grow-direction RIGHT)
(ly:beam::print grob)))
((ly:stencil? (ly:beam::print grob)) ;; delete this?
(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))))
(space-between-beams (* 0.46 (ly:grob-property grob 'gap)))
(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)))
(dir-peak (if (and (ly:grob-property grob 'knee) (< number 0) (= (car beam-positions) (cdr beam-positions)))
-1
1))
(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 (/ beam-length-x first-stem-to-target-stem-length))
;; markup-a is the longest beam
(markup-a (markup #:beam beam-length-x
(if (and (ly:grob-property grob 'knee) (< number 0)(= (car beam-positions) (cdr beam-positions)))
(* dir-peak orig-slope)
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 (+ 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)))
(if (and (ly:grob-property grob 'knee) (< number 0))
(* (* 1 dir-peak) (/ (y-L n) x-L))
(* dir-peak (/ (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 0.86
(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)))
(if (and (ly:grob-property grob 'knee) (< number 0))
(* (* 1 dir-peak) (/ (y-R n) x-R))
(/ (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))
(* dir-peak (- (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*
)
)
)
%--------------------- Test ----------------------------------------------------
\relative c' {
\mark\markup { \with-color #red "A" }
\once \override Beam #'stencil = #(grow-beam-var 0)
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 4)
c,,256[c' c' c' c']
\bar "" \break
\mark\markup { \with-color #red "L" }
\once \override Beam #'positions = #'(0 . 0)
\once \override Beam #'stencil = #(grow-beam-var -5)
f,,,,,32 [ \xy f''' f,,, \xy f''' f,,, %{ \xy %} f''' f,,, \xy f''' f,,, \xyOut #11 f''']
\override Beam #'auto-knee-gap = #6
\once \override Beam #'stencil = #(grow-beam-var 5)
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
}
\pageBreak
\relative c' {
\mark\markup { \with-color #red "O" }
\once \override Beam #'positions = #'(0.2 . 0.2)
\override Beam #'auto-knee-gap = #4
\override Beam #'stencil = #(grow-beam-var -16)
c''32 [b a g
f g a b
c b a g
f g a b
\xy e,,, c''' b a
g a b c
d c b a
g a b c]
\bar "" \break
\override Beam #'auto-knee-gap = #4
\override Beam #'stencil = #(grow-beam-var 16)
c32 [b a g
f g a b
c b a g
f g a b
e,,, c''' b a
g a b c
d c b a
g a b c]
}
\relative c'' {
\mark\markup { \with-color #red "P" }
\override Beam #'stencil = #(grow-beam-var 4)
\featherDurations #(ly:make-moment 1 2)
{c32[ c c c} \featherDurations #(ly:make-moment 2 1) {c c c c]} c2.
}
\relative c'' {
\override Beam #'stencil = #(grow-beam-var 8)
\featherDurations #(ly:make-moment 1 2)
{a64 [a a a
a a a a}
\featherDurations #(ly:make-moment 2 1)
{
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|
}
\relative c {
\mark\markup { \with-color #red "Q" }
\once \override Beam #'positions = #'(0 . 0)
\once \override Beam #'stencil = #(grow-beam-var -5)
f32 [ \xy f''' f,,, \xy f''' f,,, %{ \xy %} f''' f,,, \xy f''' f,,, %\xy
\xyOut #11
f''']
}
top = \change Staff = "1"
bottom = \change Staff = "2"
music = \relative c {
\mark\markup { \with-color #red "R" }
\override Beam #'auto-knee-gap = #0
\set tupletSpannerDuration = #(ly:make-moment 1 16)
\override TupletNumber #'transparent = ##t
\override Beam #'stencil = #(grow-beam-var -1)
\once \override Beam #'positions = #'(4.5 . 5)
\times 2/3 {
\bottom c32[ g' \top eis']
\once \override Beam #'positions = #'(-4.5 . -6)
c'[ e, \bottom g,]
\top e''[ \bottom c,, \top g'']
}
\override Beam #'stencil = #(grow-beam-var 2)
%\once \override Beam #'positions = #'(3.5 . 5)
\once \override Beam #'positions = #'(4 . 4)
\times 4/5 {
\bottom c,,64[ \top \xy g'' \xy e' \bottom c,, \top c'']
}
}
\score {
\new PianoStaff <<
\new Staff = "1" {
s4
}
\new Staff = "2" {
\clef bass
\music
}
>>
}
Dann weiter viel Spaß mit den Beams.
Harm
P.S.
Wenn du mal in Berlin bist lade ich dich auf ein Kaffee ein :)
Gibt's auch Kuchen dazu? ;)
-
Hallo kil,
Kneed-Beams
Für kneed-Beams gibts noch ein paar Besonderheiten.
(...)
Überstehende Notenhälse
(...)Um diesen Notenhals zu verkürzen hat sich David etwas einfallen lassen, was ich dann in eine Funktion verwandelt habe:
#(define ((stem-length y) grob)
(ly:grob-set-property! grob 'length y)
(ly:stem::print grob))
xyOut =
#(define-music-function (parser location y-length)(number?)
#{
\once \override Stem #'stencil = #(stem-length $y-length)
#})
Leider gibt es zwei Einschränkungen mit dieser Funktion: Sie funktioniert nicht mit "2.14.2" sondern erst mit höheren Versionen. Ich habe es mit "2.15.13" getestet. Darüberhinaus funktioniert sie nicht in Verbindung mit \change Staff.
Vielleicht fällt uns ja noch etwas besseres ein.
Ich hab' diese Funktion nochmal bearbeitet. Jetzt klappts auch mit \change Staff.
(Die construction-helper kann man einkommentieren, muß man aber natürlich nicht.)
Anwendung bei Buchstabe "Q" und "R".
Der Code dafür kann in ein "2.14.2"-file gepackt werden, aber damit er funktioniert ist "2.15.13" oder höher als Programm immer noch erforderlich.
% xyOut needs \version "2.15.13"
\version "2.14.2"
#(define ((stem-length y) grob)
(if (ly:stencil? (ly:stem::print grob))
(begin
(and
(ly:grob-set-property! grob 'length y)
;;(ly:grob-set-property! grob 'color red);; construction-helper, comment out!
;;(ly:grob-set-property! grob 'layer 6) ;; construction-helper, comment out!
)
(ly:stem::print grob))
))
xyOut =
#(define-music-function (parser location y-length)(number?)
#{
\once \override Stem #'stencil = #(stem-length $y-length)
#})
Zu \featherDurations
David hat sich featherDurationsTest einfallen lassen. Ich habe dann noch ein wenig Kosmetik betrieben, so daß Du idR das gleiche Argument wie für grow-dir-var benutzen kannst.
Anwendung bei Buchstabe "P"
Allerdings unterliegt diese Funktion denselben Beschränkungen wie \featherDurations. D.h. manchmal gibt es unverhoffte und ungewollte Veränderungen beim spacing der Noten.
Sie funktioniert aber auch umgekehrt, d.h. erst rit. dann accel. -> Buchstabe "S"
Wenn es funktioniert wie gewünscht, ist es ein schönes feature.
\version "2.14.2"
#(define (moment=? a b)
(not (or (ly:moment<? a b) (ly:moment<? b a))))
#(define (moment>? a b)
(not (or (ly:moment<? a b) (moment=? a b))))
featherDurationsTest=
#(define-music-function (parser location factor turnaround-orig argument)
(ly:moment? number? ly:music?)
(let* ((orig-duration (ly:music-length argument))
(multiplier (ly:make-moment 1 1))
(turnaround (if (and (integer? turnaround-orig) (>= turnaround-orig 0))
turnaround-orig
(inexact->exact (floor (abs turnaround-orig)))))
(elements (ly:music-property argument 'elements))
(dif (- (length elements) turnaround))
(lth (cond ((>= dif 0) dif)
(else (length elements))))
(peak-multiplier
(reduce
(lambda (mom prev) (ly:moment-mul mom prev))
multiplier
(make-list turnaround factor)))
(end-multiplier
(reduce
(lambda (mom prev) (ly:moment-mul mom prev))
peak-multiplier
(append
(list peak-multiplier)
(make-list lth ;;(- (length elements) turnaround)
(ly:moment-div (ly:make-moment 1 1) factor)))))
(comparison
(if (< (ly:moment-main-numerator factor) (ly:moment-main-denominator factor))
(lambda (a b) (ly:moment<? a b))
(lambda (a b) (moment>? a b)))))
(music-map
(lambda (mus)
(if (and (eq? (ly:music-property mus 'name) 'EventChord)
(< 0 (ly:moment-main-denominator (ly:music-length mus))))
(begin
;;(display multiplier) (newline) ; shows pattern of modification
(ly:music-compress mus multiplier)
(if (comparison peak-multiplier multiplier)
(set! multiplier (ly:moment-mul factor multiplier))
(begin
(set! multiplier (ly:moment-div multiplier factor))
(set! peak-multiplier end-multiplier)))))
mus)
argument)
(ly:music-compress
argument
(ly:moment-div orig-duration (ly:music-length argument)))
argument))
Im Anhang das komplette file.
Gruß,
Harm
-
Das sieht echt Spitze aus. :)
Ganz große Klasse, harm6,
meint Trulli
-
Wow Harm, wie Trulli sagt, große Klasse!! Großes Dankschön an dir und auch David! Vielleicht schafft es sogar als Default in die nächste Version!
Ich frage mich ob man mit dieser Konstruktion auch das Gegenteil erzeugen kann... also schnelle Töne die allmählich langsamer werden und dann wieder schneller. Kommt auch mal vor!
Gibt's auch Kuchen dazu?
Aber klar! Je nach Tageszeit Bier statt Kaffee, oder Getränk deiner Wahl ;D
Gruß
kil
-
Hallo kil,
Ich frage mich ob man mit dieser Konstruktion auch das Gegenteil erzeugen kann... also schnelle Töne die allmählich langsamer werden und dann wieder schneller. Kommt auch mal vor!
Dein Wunsch ist mir Befehl. ;D
Die xyOut-Funktion zur Veränderung der Notenhälse ist jetzt auch in "2.14.2" anwendbar. Allerdings führten meine Versuche die stems automatisch anzupassen zu einem instabilen Ergebnis. Im Moment mußt Du also jeden stem manuell anpassen. Das wird aber (hoffe ich) nur bei kneed-beams in Verbindung mit \change Staff nötig sein. Bei jeder anderen Anwendung sind die Notenhälse von vornherein richtig gesetzt.
Viele Grüße,
Harm
P.S. David hat sein \featherDurationTest zwar noch mal bearbeitet, aber aus irgendeinem Grund funktioniert es nicht so gut wie die vorherige Fassung. Die neue Fassung habe ich deshalb eingefügt (vielleicht interessiert es ja jemanden), aber auskommentiert und die ältere benutzt.
Der mittlerweile auf fünf Seiten angewachsene Test ist größtenteils ebenfalls auskommentiert.
-
:o
Da hast du dir ein zweites Stück Kuchen verdient! Mensch! Echt Klasse!
-
Hallo zusammen,
die xyOut-Funktion arbeitet nicht mehr, da das angegangene property nicht mehr existiert.
Insoweit habe ich diese Funktion durch die neue `tweakStemLength' ersetzt und stelle den gesamten Code noch mal in den Anhang.
Getestet mit 2.18.2 und 2.19.48.
Gruß,
Harm