Re: scheme-question about accumulating lists of lists
Hi again, Replying twice to myself in a row, how is that :) A little tired I guess ... > > Note that the above will only work if the last 'blue item' has 3 elements, > > you'd > > need to adapt for other use case (which also 'speak' in favor of the cleaner > > approach. > Actually, I didn't like what I wrote, here is a slightly better code: And here is a corrected version: the code in the mail I'm answering now would not return proper (expected) results for any other operator then car ... this one will let you really walk :) (use-modules (ice-9 match)) (define blue (cons '(a b c) (cons '(1 2 3) '(x y z (define fox (cons '(a b c) (cons '(1 2 3) (cons '(x y z) '() (define (blue-walk blue proc) (let loop ((blue blue) (result '())) (match blue ((a . rest) (if (pair? a) (loop rest (cons (proc a) result)) (reverse! (cons (proc (cons a rest)) result (() (reverse! result) scheme@(guile-user)> (load "blue.scm") ;;; note: source file /usr/alto/projects/guile/blue.scm ;;; ... scheme@(guile-user)> (blue-walk blue car) $2 = (a 1 x) scheme@(guile-user)> (blue-walk fox car) $3 = (a 1 x) scheme@(guile-user)> (blue-walk blue cdr) $4 = ((b c) (2 3) (y z)) scheme@(guile-user)> (blue-walk fox cdr) $5 = ((b c) (2 3) (y z)) Cheers, David pgpj47BxMMxuy.pgp Description: OpenPGP digital signature ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: scheme-question about accumulating lists of lists
Hi again, > Note that the above will only work if the last 'blue item' has 3 elements, > you'd > need to adapt for other use case (which also 'speak' in favor of the cleaner > approach. Actually, I didn't like what I wrote, here is a slightly better code: (use-modules (ice-9 match)) (define (blue-walk blue proc) (let loop ((blue blue) (result '())) (match blue ((a . rest) (if (pair? a) (loop rest (cons (proc a) result)) (reverse! (cons a result (() (reverse! result) It solves the above note (it avoids to have to know how many elements the last pair has), and also let you process both 'your' structure and the 'cleaner' one: (define blue (cons '(a b c) (cons '(1 2 3) '(x y z (define fox (cons '(a b c) (cons '(1 2 3) (cons '(x y z) '() scheme@(guile-user)> (load "blue.scm") ;;; note: source file /usr/alto/projects/guile/blue.scm ;;; newer than ... scheme@(guile-user)> (blue-walk fox car) $2 = (a 1 x) scheme@(guile-user)> (blue-walk blue car) $3 = (a 1 x) Cheers, David pgpq3Krn_OVTN.pgp Description: OpenPGP digital signature ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: scheme-question about accumulating lists of lists
Hi Thomas, > Failing example: > (map > car > (cons '(a b c) (cons '(1 2 3) '(x y z > One way to make it work is to convert the initial pair (cons '(1 2 3) > '(x y z)) to a list of lists, i.e (cons '(1 2 3) (list '(x y z))) > The question is: is it the only and/or best way? It sounds a lot cleaner to me, because, in the end, it is as if: (cons '(a b c) (cons '(1 2 3) (cons '(x y z) '( which is 'consistent all the way down, so to speak, and will let you use build-in scheme ops like map, fold, ... If you want to keep the original structure though, I'd use (ice-9 match) and recurse: (use-modules (ice-9 match)) (define blue (cons '(a b c) (cons '(1 2 3) '(x y z (define (blue-walk blue proc) (let loop ((blue blue) (result '())) (match blue ((x y z) (reverse! (cons x result))) ((a . rest) (loop rest (cons (proc a) result)) scheme@(guile-user)> (load "blue.scm") ;;; compiling /usr/alto/projects/guile/blue.scm ;;; compiled /home/david/.cache/guile/ccache/2.2-LE-8-3.A/usr/alto/projects/guile/blue.scm.go scheme@(guile-user)> (blue-walk blue car) $8 = (a 1 x) Note that the above will only work if the last 'blue item' has 3 elements, you'd need to adapt for other use case (which also 'speak' in favor of the cleaner approach. David pgpE8DMTMeHFF.pgp Description: OpenPGP digital signature ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re[2]: Slur with left and/or right arrow head
Aaron, Harm Could I please comment on just one feature? The overrides to add or inhibit arrow-heads at the left and right ends of the Slur are: \override Slur.details.arrow-left = #LEFT \override Slur.details.arrow-right = #RIGHT \override Slur.details.arrow-left = ##f \override Slur.details.arrow-right = ##f This slightly confused me, especially when I tried \override Slur.details.arrow-right = #LEFT which draws a left-pointing arrow-head at the right end of the Slur. Something I don't think anyone would want. Why not have the simpler and less confusing \override Slur.details.arrow-left = ##t \override Slur.details.arrow-right = ##t \override Slur.details.arrow-left = ##f \override Slur.details.arrow-right = ##f ? Trevor -- Original Message -- From: "Thomas Morley" To: "Aaron Hill" ; "Lukas-Fabian Moser" Cc: "lilypond-user" Sent: 19/04/2019 22:03:31 Subject: Re: Slur with left and/or right arrow head Am Di., 16. Apr. 2019 um 23:45 Uhr schrieb Aaron Hill : On 2019-04-16 10:37 am, Thomas Morley wrote: > Am Mo., 15. Apr. 2019 um 19:26 Uhr schrieb Lukas-Fabian Moser > : >> >> Folks, >> >> in >> https://archiv.lilypondforum.de/index.php?topic=1744.msg9669#msg9669, >> Harm invented a truly wonderful new feature allowing to add an arrow >> head to the right end of a Slur (or, for that matter, a Tie, >> PhrasingSlur etc.). I reproduce it here with only trivial changes >> (mainly omitting parser/location). >> >> Now I also need slurs with arrows pointing to the left (and ideally, >> also the option to have an arrow tip at both ends of the Slur). At >> first >> glance the asymmetry favoring the right hand side of a Slur seems to >> be >> hard-coded pretty deeply in Harm's code. Is there a cheap way to add a >> choice of "left or right end" (if not even the "or/and" possibility)? >> >> Best >> Lukas > > Hi Lukas, > > I started to implement the functionality, finally I more or less > rewrote anything. > As David K once said: rewriting all means at least knowing where the > bugs are... Harm, There is an annoying optical issue where using the angle of the curve at the end points does not work well for an arrow head that partially overlaps the curve. Instead, one needs to consider the slope of the curve a little inwards from the ends so that the arrow appears to be aligned properly. I took a stab at patching your code to address this. This involved some additional computational work for various metrics of a Bezier curve. See the attached files. Among the things I changed is that the code that adds the arrows to the ends of the curve no longer applies an offset. This offset was strictly horizontal which did not work well for more heavily rotated arrows. Instead, the offset is done within the code that computes and rotates the arrow, so that the center of rotation is properly defined. Hi Aaron, meanwhile I think I understand more about Beziers, many thanks for your and David's explanations. Also, I looked entirely through your code and probably understood how you do things. As already said I stumbled across some procedures being called over and over, also I asked myself why we need the entire length of the Bezier, if we are interested only in a short part at start/end. So I wrote a procedure (relying on `split-bezier´ from bezier-tools.scm), where the Bezier is splitted, i.e. two sets of new control-points are returned. For those new control-points the direct line between first and last point is calculated. If this is lower than a certain treshold, we have control-points for a Bezier where we can calculate the angle, otherwise it continues to recurse until the goal is reached. Relying on start/end of the original Bezier it's first or last of the new points, which now can serve for calculating the angle. Function-calls are drastically reduced, performance time is reduced and code simplified imho. One thing I noticed are not so nice printed arrows for short Beziers like Repeat/LaissezVibrerTie. Likely due to the width of the arrowhead, _within_ this width the Bezier is "too active", so to speak. In general I've found your function to calculate a point on the Bezier and to calculate an angle at a certain point of the Bezier _very_ helpful. What do you think adding it to bezier-tools.scm? Attached the newest code. WYT? Thanks, Harm @ Lukas Up to now I didn't tackle the arrow-left/right LEFT/RIGHT thing, I first wanted to fight my way through the code for Beziers. Probably tomorrow, hopefuly ...___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Slur with left and/or right arrow head
Am Di., 16. Apr. 2019 um 23:45 Uhr schrieb Aaron Hill : > > On 2019-04-16 10:37 am, Thomas Morley wrote: > > Am Mo., 15. Apr. 2019 um 19:26 Uhr schrieb Lukas-Fabian Moser > > : > >> > >> Folks, > >> > >> in > >> https://archiv.lilypondforum.de/index.php?topic=1744.msg9669#msg9669, > >> Harm invented a truly wonderful new feature allowing to add an arrow > >> head to the right end of a Slur (or, for that matter, a Tie, > >> PhrasingSlur etc.). I reproduce it here with only trivial changes > >> (mainly omitting parser/location). > >> > >> Now I also need slurs with arrows pointing to the left (and ideally, > >> also the option to have an arrow tip at both ends of the Slur). At > >> first > >> glance the asymmetry favoring the right hand side of a Slur seems to > >> be > >> hard-coded pretty deeply in Harm's code. Is there a cheap way to add a > >> choice of "left or right end" (if not even the "or/and" possibility)? > >> > >> Best > >> Lukas > > > > Hi Lukas, > > > > I started to implement the functionality, finally I more or less > > rewrote anything. > > As David K once said: rewriting all means at least knowing where the > > bugs are... > > Harm, > > There is an annoying optical issue where using the angle of the curve at > the end points does not work well for an arrow head that partially > overlaps the curve. Instead, one needs to consider the slope of the > curve a little inwards from the ends so that the arrow appears to be > aligned properly. > > I took a stab at patching your code to address this. This involved some > additional computational work for various metrics of a Bezier curve. > See the attached files. > > Among the things I changed is that the code that adds the arrows to the > ends of the curve no longer applies an offset. This offset was strictly > horizontal which did not work well for more heavily rotated arrows. > Instead, the offset is done within the code that computes and rotates > the arrow, so that the center of rotation is properly defined. Hi Aaron, meanwhile I think I understand more about Beziers, many thanks for your and David's explanations. Also, I looked entirely through your code and probably understood how you do things. As already said I stumbled across some procedures being called over and over, also I asked myself why we need the entire length of the Bezier, if we are interested only in a short part at start/end. So I wrote a procedure (relying on `split-bezier´ from bezier-tools.scm), where the Bezier is splitted, i.e. two sets of new control-points are returned. For those new control-points the direct line between first and last point is calculated. If this is lower than a certain treshold, we have control-points for a Bezier where we can calculate the angle, otherwise it continues to recurse until the goal is reached. Relying on start/end of the original Bezier it's first or last of the new points, which now can serve for calculating the angle. Function-calls are drastically reduced, performance time is reduced and code simplified imho. One thing I noticed are not so nice printed arrows for short Beziers like Repeat/LaissezVibrerTie. Likely due to the width of the arrowhead, _within_ this width the Bezier is "too active", so to speak. In general I've found your function to calculate a point on the Bezier and to calculate an angle at a certain point of the Bezier _very_ helpful. What do you think adding it to bezier-tools.scm? Attached the newest code. WYT? Thanks, Harm @ Lukas Up to now I didn't tackle the arrow-left/right LEFT/RIGHT thing, I first wanted to fight my way through the code for Beziers. Probably tomorrow, hopefuly ... \version "2.19.82" %% Thanks to Aaron Hill %% http://lists.gnu.org/archive/html/lilypond-user/2019-04/msg00240.html %% Does not work for 2.18.2 because of %% - grob::name (could be replaced by grob-name, see p.e. LSR) %% - minimum-length-after-break (no replacement possible, only used in %% the examples, though) #(ly:load "bezier-tools.scm") #(define (note-column-bounded? dir grob) "Checks wether @var{grob} is a spanner and whether the spanner is bounded in @var{dir}-direction by a note-column." (if (ly:spanner? grob) (grob::has-interface (ly:spanner-bound grob dir) 'note-column-interface) #f)) #(define (offset-number-pair-list l1 l2) "Offset the number-pairs of @var{l1} by the matching number-pairs of @var{l2}" ;; NB no type-checking or checking for equal lengths is done here (map (lambda (p1 p2) (offset-add p1 p2)) l1 l2)) #(define (bezier::point control-points t) "Given a Bezier curve of arbitrary degree specified by @var{control-points}, compute the point at the specified position @var{t}." (if (< 1 (length control-points)) (let ((q0 (bezier::point (drop-right control-points 1) t)) (q1 (bezier::point (drop control-points 1) t))) (cons (+ (* (car q0) (- 1 t)) (* (car q1) t)) (+ (* (cdr q0) (- 1 t)) (* (cdr q1) t (car
Re: Slur with left and/or right arrow head
Am Fr., 19. Apr. 2019 um 18:01 Uhr schrieb Aaron Hill : > > On 2019-04-19 3:29 am, Thomas Morley wrote: > > Am Mi., 17. Apr. 2019 um 21:16 Uhr schrieb Thomas Morley > > : > >> > >> Am Di., 16. Apr. 2019 um 23:45 Uhr schrieb Aaron Hill > > > >> > Also, I "fixed" the font-size issue by bypassing the font settings > >> > within the grob itself, because simply scaling the glyph results in > >> > thicker lines. So while font-size is now consistent between the > >> > different grobs, it is unfortunately now a hard-coded value. I am > >> > uncertain whether this tradeoff would be acceptable. > >> > >> Not sure either, why does Tie has a font-size property at all? > > > > Hi Aaron, > > > > still on the journey to understand all subtleties of your code... > > > > One detail: meanwhile I don't think it's nice hardcoding the > > font-size, looks bad for high or low staff-spaces. > > > > How about looking at staff-space and derive a suitable value from it? > > I.e. in `curve-adjusted-arrow-head´: > > > > [...] > > (let* ((staff-space (ly:staff-symbol-staff-space curve)) > > ;; reducing fs-from-staff-space a bit looks nicer > > (fs-from-staff-space (1- (magnification->font-size > > staff-space))) > > (grob-font > >(ly:paper-get-font > > (ly:grob-layout curve) > > `(((font-encoding . fetaMusic) > > (font-size . ,fs-from-staff-space) > > [...] > > Seems a reasonable approach, but isn't font-size already relative to > staff-space? > > My understanding is that a 20pt staff results in a 5pt staff-space and a > font of 11pt at font-size 0. If you change the staff size, fonts will > scale accordingly (unless you are using something like \abs-fontsize). > That means that a font-size of 0 will always be 11/5 of the staff-space. > > So if the issue is the arrow head being too big, then we should only > need to set the font-size to a smaller, though still constant, value. Look at the attached images, the one with fixed font-sizes does not respond to changed staff-space staffSize = #(define-music-function (new-size) (number?) #{ \set fontSize = #new-size \override StaffSymbol.staff-space = #(magstep new-size) \override StaffSymbol.thickness = #(magstep new-size) #}) mus = { \pointing-curve Slur \pointing-curve Tie b4( b b b) b1~ b } << \new Staff \with { \staffSize #5 } \mus \new Staff \mus \new Staff \with { \staffSize #-5 } \mus >> I think it's because you used ly:paper-get-font. Probably it's also possible to apply current 'output-scale to get things correct (not tested) Cheers, Harm ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Slur with left and/or right arrow head
On 2019-04-19 3:29 am, Thomas Morley wrote: Am Mi., 17. Apr. 2019 um 21:16 Uhr schrieb Thomas Morley : Am Di., 16. Apr. 2019 um 23:45 Uhr schrieb Aaron Hill > Also, I "fixed" the font-size issue by bypassing the font settings > within the grob itself, because simply scaling the glyph results in > thicker lines. So while font-size is now consistent between the > different grobs, it is unfortunately now a hard-coded value. I am > uncertain whether this tradeoff would be acceptable. Not sure either, why does Tie has a font-size property at all? Hi Aaron, still on the journey to understand all subtleties of your code... One detail: meanwhile I don't think it's nice hardcoding the font-size, looks bad for high or low staff-spaces. How about looking at staff-space and derive a suitable value from it? I.e. in `curve-adjusted-arrow-head´: [...] (let* ((staff-space (ly:staff-symbol-staff-space curve)) ;; reducing fs-from-staff-space a bit looks nicer (fs-from-staff-space (1- (magnification->font-size staff-space))) (grob-font (ly:paper-get-font (ly:grob-layout curve) `(((font-encoding . fetaMusic) (font-size . ,fs-from-staff-space) [...] Seems a reasonable approach, but isn't font-size already relative to staff-space? My understanding is that a 20pt staff results in a 5pt staff-space and a font of 11pt at font-size 0. If you change the staff size, fonts will scale accordingly (unless you are using something like \abs-fontsize). That means that a font-size of 0 will always be 11/5 of the staff-space. So if the issue is the arrow head being too big, then we should only need to set the font-size to a smaller, though still constant, value. The main reason I was unhappy with hard-coding the size is that for some slurs/ties, a user might want a larger arrow head, meaning we should ideally be listening to font-size of the grob so each individual curve could have its own sized arrow heads. For instance, PhrasingSlurs, which typically extend a larger distance, could use a larger arrow head. But shorter curves read better with smaller arrow heads. So any hard-coded size means all arrows are the same. Since Ties have a default font-size of -6, a user of this code would need to manually override that to something suitable just as they will need to provide a value for Slurs and PhrasingSlurs. Providing they are not using the debug annotations, then font-size for any of these grobs is unused as a property, so we can party on it without concern. (Well, the only concern is that we document things clearly, lest folks are confused why slurs and ties seem to behave differently without the overrides.) -- Aaron Hill ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: scheme-question about accumulating lists of lists
Am Fr., 19. Apr. 2019 um 17:09 Uhr schrieb Malte Meyn : > > > > Am 19.04.19 um 16:35 schrieb Thomas Morley: > > I could do > > (cons '(a b c) (list (car (list-pair)) (cdr (list-pair > > and to get the last list: (last ...) > > Looksy clumsy, though. > > > > Any better method? > > I’m not sure what you want to do here. But maybe it would be easier to > convert the pair of lists to a lists of lists first? I want to run procedures over constructed lists of lists, while the initial first entry is a pair. Failing example: (map car (cons '(a b c) (cons '(1 2 3) '(x y z One way to make it work is to convert the initial pair (cons '(1 2 3) '(x y z)) to a list of lists, i.e (cons '(1 2 3) (list '(x y z))) The question is: is it the only and/or best way? Thanks, Harm ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: scheme-question about accumulating lists of lists
Am 19.04.19 um 16:35 schrieb Thomas Morley: I could do (cons '(a b c) (list (car (list-pair)) (cdr (list-pair and to get the last list: (last ...) Looksy clumsy, though. Any better method? I’m not sure what you want to do here. But maybe it would be easier to convert the pair of lists to a lists of lists first? \version "2.21.0" #(begin (define (list-pair->list-list the-list-pair) (list (car the-list-pair) (cdr the-list-pair))) (define foo '((a b c) . (d e f))) (display foo) (newline) (display (list-pair->list-list foo))) ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
scheme-question about accumulating lists of lists
Hi all, let's say I've a procedure building a pair of lists. Actually it's a built-in procedure, so I can't change it. For the sake of simplicity let's take: (define (list-pair) (cons '(1 2 3) '(x y z))) (list-pair) returns ((1 2 3) x y z) (cdr (list-pair)) returns the second list, i.e. (x y z) All fine so far. Now I add another list (cons '(a b c) (list-pair)) => ((a b c) (1 2 3) x y z) Now it's starts getting inconveniant to get the last list, i.e. (x y z) (and I may add an arbitrary number of lists this way) I could do (cons '(a b c) (list (car (list-pair)) (cdr (list-pair and to get the last list: (last ...) Looksy clumsy, though. Any better method? Thanks, Harm ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Slur with left and/or right arrow head
Am Mi., 17. Apr. 2019 um 21:16 Uhr schrieb Thomas Morley : > > Am Di., 16. Apr. 2019 um 23:45 Uhr schrieb Aaron Hill > > Also, I "fixed" the font-size issue by bypassing the font settings > > within the grob itself, because simply scaling the glyph results in > > thicker lines. So while font-size is now consistent between the > > different grobs, it is unfortunately now a hard-coded value. I am > > uncertain whether this tradeoff would be acceptable. > > Not sure either, why does Tie has a font-size property at all? Hi Aaron, still on the journey to understand all subtleties of your code... One detail: meanwhile I don't think it's nice hardcoding the font-size, looks bad for high or low staff-spaces. How about looking at staff-space and derive a suitable value from it? I.e. in `curve-adjusted-arrow-head´: [...] (let* ((staff-space (ly:staff-symbol-staff-space curve)) ;; reducing fs-from-staff-space a bit looks nicer (fs-from-staff-space (1- (magnification->font-size staff-space))) (grob-font (ly:paper-get-font (ly:grob-layout curve) `(((font-encoding . fetaMusic) (font-size . ,fs-from-staff-space) [...] Best, Harm ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user