Thank you, Valentin. I stumbled upon this snipped a while before, and it’s
really useful for shaping more complex slurs. Still, it’s not what I’m after,
I’m trying to experiment, if Lilypond can find some of the more complex slur
shapes. But for this, I have to work around the limitation that lilypond’s
spanner-design imposes on slurs.
I’m planning to do some documentation on how you can actually use this for
nice slurs, but for now I’ve created an example demonstrating why this does
matter. Please take a look at the last page, it’s a comparisation of the
shapeII-placed example from your linked post and an automatically placed one
with two little overrides. This page demonstrates that good manual placement
requires lots of knowledge and work, and should therefore be avoided if
possible. If you print it out, you will see that the manually placed slurs
actually have too uneven and too much distance from the note heads, thereby
distracting from the actual music.
Best regards,
Valentin
Am Samstag, 16. März 2019, 20:20:15 CET schrieb Valentin Villenave:
> Another possibility would be to use polar coordinates, as Janek and
> David N. tried to do a while back:
> https://lists.gnu.org/archive/html/lilypond-user/2013-11/msg00832.html
> (That code compiles very well with 2.18, but some tweaks are needed
> for 2.19 and 2.21. It may also have some duplicate functions wrt
> polar->rectangular.)
>
> I can’t remember that part of their code having ever been merged
> upstream, but this could provide you with an interesting starting
> point to actually get it included in LilyPond.
>
> Cheers,
> V.\version "2.18"
\include "shapeII-definition.ily"
\paper {
ragged-right = ##t
indent = 0
top-markup-spacing #'basic-distance = #5
}
\header {
title = "Shaping slurs: The penalty approach"
author = "Valentin Petzel"
}
\markup \vspace #1
\markup {\italic "All examples and snippets are taken from this post:"}
\markup { \typewriter "https://lists.gnu.org/archive/html/lilypond-user/2013-11/msg00832.html; }
\markup \vspace #1
\markup {
\column {
\justify {
A slur is, from a mathematical point of view naught but a planar curve,
that is, a function from an Interval into the plane, i.e.
some function γ(t)=(x(t), y(t)), where the parameter t comes from an interval.
By reparametrisation we can assume this interval to be [0, 1].
Now, a computer cannot handle arbitrary curves just like that, that’s why we use
very specific functions for the coordinates x and y, that is to say, polynomials
of limited degree n (usually n = 3 for slurs).
}
\vspace #0.5
\justify {
A polynomial of degree n can be expressed as a combination of 1=X^0, X^1, ..., X^n. The
problem with using this so called basis is that one can hardly predict the outcome of this
combination a0 + a1·X^1 + ... + an·X^n by just looking at the coefficients a0, ..., an.
}
\vspace #0.5
\justify {
This is the reason we use so called \italic "Bézier curves" instead. This means that we
use a different basis for our polynomials. Instead of monoms 1, X^1, ..., X^n one uses the so
called \italic "Bernstein polynomials" of degree n. These are n+1 polynomials that form a basis,
so we can express any polynomial of degree n as a combination of these basis polynomials.
}
\vspace #0.5
\justify {
The Bernstein polynomials B0, ..., Bn have interesting properties
(as can be see on this image https://commons.wikimedia.org/wiki/File:Bernstein_Polynomials.svg)
on the Interval [0, 1]: The outer polynomials B0 and Bn are 1 on one side and 0 on the other, while
the other polynomials B1, ..., B[n-1] are 0 on both edges and have their mass concentrated on
different parts of the interval. This means, that B0 and B1 are directly specifying the
starting and the ending value of the polynomial, while the other polynomials will specify the
extent on different parts of the interval.
}
\vspace #0.5
\justify {
If γ(t)=(x(t), y(t)), and both x and y are polynomials of degree n, that are parametrised as a
combination of the Bernstein polynomials of degree b, this gives us an interesting geometric
property:
}
\vspace #0.5
\justify {
If y = y0·B0 + ... + yn·Bn and x = x0·B0 + ... + xn·Bn, then the so called control points (x0, y0), ..., (xn, yn)
form a polygon, that somehow outlines the curve γ. This makes drawing Bézier curves on graphical
systems very intuitive (and it’s basically what you get, when drawing slurs in graphical
notation programs).
}
\vspace #0.8
\justify {
What Lilypond attempts to do is to find these control points automatically for an optimal slur. This
is done in a typical approach: For a given curve, we calculate penalty points for everything that is
bad about this curve, and thus get a general badness value of it. Then we try to find a curve that
somewhat minimizes this badness. This is an optimisation