CrossStaff Stems [gelöst]

Begonnen von kilgore, Dienstag, 8. Dezember 2020, 10:53

« vorheriges - nächstes »

kilgore

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
  }
}

}

Rudi Guggt

#1
Hallo,

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

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

LG
Rudi

harm6

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

kilgore

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

kilgore

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

harm6

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

kilgore

auch hierfür danke! Darauf wäre ich nie gekommen...