Re: scheme-question about accumulating lists of lists

2019-04-19 Thread David Pirotte
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

2019-04-19 Thread David Pirotte
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

2019-04-19 Thread David Pirotte
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

2019-04-19 Thread Trevor


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

2019-04-19 Thread Thomas Morley
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

2019-04-19 Thread Thomas Morley
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

2019-04-19 Thread 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.


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

2019-04-19 Thread Thomas Morley
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

2019-04-19 Thread 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?


\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

2019-04-19 Thread Thomas Morley
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

2019-04-19 Thread Thomas Morley
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