LilyPond中\change Staff引发的垂直间距与碰撞问题求助
LilyPond连音线与歌词碰撞问题的解决思路
问题复现
代码示例
\version "2.24.0" BassVoice = \relative d { \clef bass d2 d4 d4 | } BassVoiceLyrics = \lyricmode { Word word word } PianoRightHand = \relative g' { \clef treble s1 | \bar "|." } PianoLeftHand = \relative g' { \clef bass g,8^( \change Staff = "up" g'8 d'8^[ d'8 b8 g8 d8] g,8) | \bar "|." } \score { << \new StaffGroup << \new Staff = "Bass" << \context Staff << \context Voice = "BassVoice" { \voiceTwo \BassVoice } \new Lyrics \with { alignBelowContext = "Bass" } \lyricsto "BassVoice" \BassVoiceLyrics >> >> >> \new PianoStaff << \context Staff = "up" \with { \override VerticalAxisGroup.default-staff-staff-spacing = #'((basic-distance . 100) (minimum-distance . 100) (padding . 100) (stretchability . 100)) } << \context Voice = "PianoRightHand" { \voiceOne \PianoRightHand } >> \context Staff = "down" << \context Voice = "PianoLeftHand" { \voiceOne \PianoLeftHand } >> >> >> }
碰撞效果

问题分析
1. 为何调整default-staff-staff-spacing无效?
你之前修改的VerticalAxisGroup.default-staff-staff-spacing是同一容器内谱表的间距参数——比如它只影响PianoStaff内部左右手谱表的距离,对Bass StaffGroup和PianoStaff这两个独立的顶级布局容器之间的间距完全不起作用。
2. 为何LilyPond未自动检测碰撞?
LilyPond的自动碰撞检测默认只在同一顶级容器内生效。你的歌词属于Bass StaffGroup,连音线属于PianoStaff,二者分属不同顶级容器,系统不会跨容器计算碰撞并调整间距。
解决办法
方法一:合并顶级容器(推荐)
把Bass Staff和PianoStaff放到同一个StaffGroup里,让LilyPond可以统一处理所有元素的布局和碰撞:
\score { << \new StaffGroup << \new Staff = "Bass" << \context Staff << \context Voice = "BassVoice" { \voiceTwo \BassVoice } \new Lyrics \with { alignBelowContext = "Bass" } \lyricsto "BassVoice" \BassVoiceLyrics >> >> \new PianoStaff << \context Staff = "up" << \context Voice = "PianoRightHand" { \voiceOne \PianoRightHand } >> \context Staff = "down" << \context Voice = "PianoLeftHand" { \voiceOne \PianoLeftHand } >> >> >> >> }
这种方式下,LilyPond会自动检测连音线和歌词的碰撞并调整间距,不需要手动设置数值。
方法二:手动设置顶级容器间的间距
如果不想合并容器,可以直接调整Bass StaffGroup和PianoStaff之间的全局间距:
\score { << \new StaffGroup \with { system-system-spacing = #'((basic-distance . 60) (minimum-distance . 60)) } << \new Staff = "Bass" << \context Staff << \context Voice = "BassVoice" { \voiceTwo \BassVoice } \new Lyrics \with { alignBelowContext = "Bass" } \lyricsto "BassVoice" \BassVoiceLyrics >> >> >> \new PianoStaff << \context Staff = "up" << \context Voice = "PianoRightHand" { \voiceOne \PianoRightHand } >> \context Staff = "down" << \context Voice = "PianoLeftHand" { \voiceOne \PianoLeftHand } >> >> >> }
通过system-system-spacing设置当前StaffGroup与下方容器的基础间距和最小间距,数值可根据实际效果调整。
方法三:局部偏移连音线
如果只想调整连音线位置而不改动整体布局,可以给连音线添加垂直偏移:
PianoLeftHand = \relative g' { \clef bass g,8^( \offset #'(0 . -2) \change Staff = "up" g'8 d'8^[ d'8 b8 g8 d8] g,8) | \bar "|." }
\offset #'(0 . -2)表示将后续元素(这里是跨谱表的连音线部分)向下移动2个单位,避开歌词。
内容的提问来源于stack exchange,提问作者Jim Liddle
相关产品推荐
相关产品推荐

