I was going to post something similiar.
You're code is much more elegant with respect to linebreaks, great stuff.
Though, it will not work as desired if the beam/hairpin is distributed
over _three_ lines.
I've no clue how to make it work, admittedly it's a real rare case.
Some inline remarks to your code.
2018-02-05 0:25 GMT+01:00 David Nalesnik <david.nales...@gmail.com>:
> Hi Stefano,
> On Sun, Feb 4, 2018 at 4:09 PM, Stefano Troncaro
> <stefanotronc...@gmail.com> wrote:
>> Harm, I've been thinking about this, and perhaps you have an idea of how the
>> following can be achieved.
>> A consequence of explicitly stating the degree in which the stencil has to
>> be rotated is that if anything changes the spacing of that system it's very
>> likely that the degree of rotation will have to be manually tweaked. I was
>> thinking on how to achieve an "automatic" solution. I imagine that this
>> could be done by establishing two points of reference. In this example any
>> two points running along the Beam would serve, although the ending points of
>> two of the Stems would work just as well.
>> But all this assumes that every object has a distinct name/ID/whatever, like
>> a pointer to it which allows to recover information on it, or at least that
>> one can be given. Do you know if this is possible?
> Within a callback for Hairpin.stencil, you can get to the Beam grob by
> following pointers from the spanner bounds of the Hairpin. You can
> then calculate the Beam's slope and use that information to rotate the
> Hairpin stencil.
> \version "2.19.65"
> #(define test
> (lambda (grob)
> (let* ((lb (ly:spanner-bound grob LEFT))
> (rb (ly:spanner-bound grob RIGHT))
> (stil (ly:hairpin::print grob))
> (find (lambda (b)
> (grob::has-interface b 'note-column-interface))
> (list lb rb))))
> (if (ly:grob? bound)
> (let* ((stem (ly:grob-object bound 'stem))
> (beam (ly:grob-object stem 'beam)))
> (if (ly:grob? beam)
> (let* ((X-pos (ly:grob-property beam 'X-positions))
> (Y-pos (ly:grob-property beam 'positions))
Using atan may return unexact values if the angle is close to zero, iirc.
I suggest to use ly:angle:
(- (cdr X-pos) (car X-pos))
(- (cdr Y-pos) (car Y-pos))))
> (ang (atan (- (cdr Y-pos) (car Y-pos))
> (- (cdr X-pos) (car X-pos)))))
No need use PI then:
stil ang CENTER CENTER)
> stil (* ang (/ 180 PI)) CENTER CENTER))
> \override Hairpin.stencil = #test
> c'16\< e' g' b'\!
> b'16\< g' e' c'\!
> \once \offset positions #'(0 . 3) Beam
> c'16^\< e' g' b'\!
> \override Beam.breakable = ##t
> c'8[\< e' \break g' b']\!
> Hope this gets you started...
All the best,
lilypond-user mailing list