Deutschsprachiges LilyPond-Forum

Allgemeine Fragen und Probleme => Fragen und Probleme aller Art => Thema gestartet von: kilgore am Dienstag, 8. Dezember 2020, 10:53

Titel: CrossStaff Stems [gelöst]
Beitrag von: kilgore am Dienstag, 8. Dezember 2020, 10:53
Hallo an alle!

Es geht um die "crossStaff" Notenhälse in Klaviernotation. Kann jemand mir bitte sagen, warum der Notenhals in der linken Hand nicht mit dem Notenhals in der Rechten Hand verbindet? Sollte ganz einfach sein, sicherlich habe ich irgendein Befehl falsch platziert. Ich sehe aber nicht was falsch ist...

Danke schön!


\version "2.20.0"

right = \relative c' {
  \time 3/4
  r4 <ais\harmonic b\harmonic>8 r8 r8 ais!8-.\p
 
 
}

left = \relative c {
  r4 \crossStaff { <fis,, g>8 } r8 r4
 
}

\score {
<<
 
  \new PianoStaff <<
    \new Staff = "right" { \clef treble \right }
    \new Staff = "left" { \clef "bass_8" \left }
  >>
 
 
>>

  \layout {
\context {
    \PianoStaff
    \consists #Span_stem_engraver
  }
}

}
Titel: Antw:CrossStaff Stems
Beitrag von: Rudi Guggt am Dienstag, 8. Dezember 2020, 14:14
Hallo,

\crossStaff harmoniert nicht mit \harmonic. Nimm das weg und es funktioniert...

...oder füg es unten noch dazu.

LG
Rudi
Titel: Antw:CrossStaff Stems
Beitrag von: harm6 am Dienstag, 8. Dezember 2020, 20:11
Hallo kilgore,

schön Dich mal wieder zu sehen ;)

Die Stems verbinden sich nur wenn sie horizontal nicht zu weit auseinander liegen. Der Schwellenwert liegt bei 0.0001 staff-spaces.
Durch die Verwendung von harmonic NoteHeads wird die obere NoteColumn minimal versetzt um zu einem ansprechenden Ergenis zu kommen, allerdings reicht diese Versetzung schon aus, um den Schwellenwert zu überschreiten. Somit werden die Stems nicht mehr verbunden. Auch ist damit klar warum es funktioniert, sobald man die harmonics rausnimmt.
Manchmal ist die Verschiebung der NoteColumns gegeneinander aber auch beträchtlich (bei mehrstimmigem Geschehen, wo nur eine Stimme dann cross-staff Stems bekommen soll).
Der Span_stem_engraver regelt das nicht von sich aus (ich bin aber auch nicht sicher, ob das wünschenswert wäre).
Aber ich hatte mal einen Code geschrieben, der das fallweise automatisiert:


\version "2.20.0"

pushNC =
\once \override NoteColumn.X-offset =
  #(lambda (grob)
    (let* ((p-c (ly:grob-parent grob X))
           (p-c-elts (ly:grob-object p-c 'elements))
           (stems
             (if (ly:grob-array? p-c-elts)
                 (filter
                   (lambda (elt)(grob::has-interface elt 'stem-interface))
                   (ly:grob-array->list p-c-elts))
                 #f))
           (stems-x-exts
             (if stems
                 (map
                   (lambda (stem)
                     (ly:grob-extent
                       stem
                       (ly:grob-common-refpoint grob stem X)
                       X))
                   stems)
                 '()))
           (sane-ext
             (filter interval-sane? stems-x-exts))
           (cars (map car sane-ext)))
    (if (pair? cars)
        (abs (- (apply max cars)  (apply min cars)))
        0)))

right = \relative c' {
  \time 3/4
  r4 \pushNC <ais\harmonic b\harmonic>8 r8 r8 ais!8-.\p
}

left = \relative c {
  r4 \crossStaff { <fis,, g>8 } r8 r4
}

\score {
  \new PianoStaff <<
    \new Staff = "right" { \clef treble \right }
    \new Staff = "left" { \clef "bass_8" \left }
  >>
  \layout {
    \context {
      \PianoStaff
      \consists #Span_stem_engraver
    }
  }
}


Gruß,
  Harm
Titel: Antw:CrossStaff Stems
Beitrag von: kilgore am Mittwoch, 9. Dezember 2020, 10:09
Danke Rudi, und danke harm6!

Immer wieder interessant, die neue Sachen die man bei Lilypond entdeckt. Ich wäre nie darauf gekommen!

@harm6 - irgendwann muss ich mal Unterricht bei dir nehmen, ich will sowas auch bauen können...!  :o
Titel: Antw:CrossStaff Stems
Beitrag von: kilgore am Montag, 8. Februar 2021, 15:46
Hallo an alle!

Ich dachte, mein Thema war mit den letzten Antworten schon gelöst. Leider bin ich gerade auf ein Problem damit gestoßen.

Die Lösungen von Rudi und harm6 funktionieren für Klavier alleine. Aber in der Partitur, wo andere Stimmen drüber liegen, klappt es auf einmal nicht mehr.


\version "2.20.0"

pushNC =
\once \override NoteColumn.X-offset =
  #(lambda (grob)
    (let* ((p-c (ly:grob-parent grob X))
           (p-c-elts (ly:grob-object p-c 'elements))
           (stems
             (if (ly:grob-array? p-c-elts)
                 (filter
                   (lambda (elt)(grob::has-interface elt 'stem-interface))
                   (ly:grob-array->list p-c-elts))
                 #f))
           (stems-x-exts
             (if stems
                 (map
                   (lambda (stem)
                     (ly:grob-extent
                       stem
                       (ly:grob-common-refpoint grob stem X)
                       X))
                   stems)
                 '()))
           (sane-ext
             (filter interval-sane? stems-x-exts))
           (cars (map car sane-ext)))
    (if (pair? cars)
        (abs (- (apply max cars)  (apply min cars)))
        0)))
 
 
stoerung = \relative c' {
c''2
}

right = \relative c' {
   \set PianoStaff.instrumentName = "Piano"
  \set PianoStaff.shortInstrumentName = "Pno"
  \time 2/4

  \tuplet 3/2 { \pushNC <cis\harmonic d\harmonic>8 r8 \pushNC <d\harmonic es\harmonic> }
  r4
               
}

left = \relative c, {
  \clef "bass_8"

  \once \override TupletBracket.transparent = ##t
  \once \override TupletNumber.transparent = ##t
  \tuplet 3/2 { \crossStaff <a bes>8 r8 \crossStaff <ais b!> } r4
}

\score {
  <<
  \new Staff { \stoerung }
 
  \new PianoStaff <<
    \new Staff = "right" { \clef treble \right }
    \new Staff = "left" { \clef "bass_8" \left }
  >>
  >>
  \layout {
    \context {
      \PianoStaff
      \consists #Span_stem_engraver
    }
  }
}


Hat jemand ein Idee wie man das löst, auch wenn andere Stimmen mit dabei sind? Danke!

Viele Grüße,
kil
Titel: Antw:CrossStaff Stems
Beitrag von: harm6 am Dienstag, 9. Februar 2021, 01:45
Der override `pushNC` wird durch den obersten Stem irritiert.

Mit dem Code unten kannst Du einen Stem mittels `noCrossStaffStem` von der Berechnung ausschließen. Somit kann Dein Beispiel erfolgreich werden. Ich habe aber den Eindruck, daß kann noch nicht der Weisheit letzter Schluß sein...


\version "2.20.0"

pushNC =
\once \override NoteColumn.X-offset =
  #(lambda (grob)
    (let* ((p-c (ly:grob-parent grob X))
           (p-c-elts (ly:grob-object p-c 'elements))
           (stems
             (if (ly:grob-array? p-c-elts)
                 (filter
                   (lambda (grob-elt)
                     (and
                       ;; select stems
                       (grob::has-interface grob-elt 'stem-interface)
                       ;; exclude cross-staff stems
                       (not
                         (grob::has-interface
                           (ly:grob-parent grob-elt X)
                           'stem-interface))
                       ;; exclude stems with details.cross-staff set to false
                       (assoc-get
                         'cross-staff
                         (ly:grob-property grob-elt 'details)
                         #t)))
                   (ly:grob-array->list p-c-elts))
                 #f))
           (stems-x-exts
             (if stems
                 (map
                   (lambda (stem)
                     (ly:grob-extent
                       stem
                       (ly:grob-common-refpoint grob stem X)
                       X))
                   stems)
                 '()))
           (sane-ext
             (filter interval-sane? stems-x-exts))
           (cars (map car sane-ext)))
    (if (pair? cars)
        (abs (- (apply max cars)  (apply min cars)))
        0)))
       
noCrossStaffStem = \override Stem.details.cross-staff = ##f


stoerung = \relative c' {
  \noCrossStaffStem
  c''2
}

right = \relative c' {
  \set PianoStaff.instrumentName = "Piano"
  \set PianoStaff.shortInstrumentName = "Pno"
  \time 2/4

  \tuplet 3/2 { \pushNC <cis\harmonic d\harmonic>8 r8 \pushNC <d\harmonic es\harmonic> }
  r4         
}

left = \relative c, {
  \clef "bass_8"

  \once \override TupletBracket.transparent = ##t
  \once \override TupletNumber.transparent = ##t
  \tuplet 3/2 { \crossStaff <a bes>8 r8 \crossStaff <ais b!> }
  r4
}

\score {
  <<
    \new Staff { \stoerung }
   
    \new PianoStaff
    <<
      \new Staff = "right" { \clef treble \right }
      \new Staff = "left" { \clef "bass_8" \left }
    >>
  >>
  \layout {
    \context {
      \PianoStaff
      \consists #Span_stem_engraver
    }
  }
}



Gruß,
  Harm
Titel: Antw:CrossStaff Stems
Beitrag von: kilgore am Mittwoch, 10. Februar 2021, 15:43
auch hierfür danke! Darauf wäre ich nie gekommen...