Merge branch 'master' of git.sv.gnu.org:/srv/git/lilypond
[lilypond/mpolesky.git] / lily / bezier-bow.cc
blob35a54ef7044ca4fd70b2dbbc10b625af3ebd6637
1 /*
2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1998--2010 Jan Nieuwenhuizen <janneke@gnu.org>
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
20 #include "misc.hh"
21 #include "bezier.hh"
23 static Real
24 F0_1 (Real x)
26 return 2 / M_PI *atan (M_PI *x / 2);
29 Real
30 slur_height (Real width, Real h_inf, Real r_0)
32 return F0_1 (width * r_0 / h_inf) * h_inf;
36 ^ x x
38 height <indent>
40 v x x
44 For small w, the height should be proportional to w, for w ->
45 infinity, the height should rise to a limit asymptotically.
47 Hence we take F (x) such that
48 F (0) = 0 , F' (0) = 1, and F (infty) = 1
50 and use
52 h = h_infinity * F (x * r_0 / h_infinity)
55 Examples:
57 * F (x) = 2/pi * atan (pi x/2)
59 * F (x) = 1/alpha * x^alpha / (1 + x^alpha)
61 * (etc.)
63 [with the 2nd recipe you can determine how quickly the conversion from
64 `small' slurs to `big' slurs occurs.]
66 Although this might seem cand_idates to SCM-ify, it is not all clear
67 which parameters (ie. h_inf, r_0, F (.)) should be candidates for
68 this. At present h_inf and r_0 come from layout settings, but we did
69 no experiments for determining the best combinations of F, h_inf and
70 r_0.
73 The indent is proportional to the height of the slur for small
74 slurs. For large slurs, this gives a certain hookiness at the end,
75 so we increase the indent.
77 indent = G (w)
79 w -> 0, G (w) -> .33 w
82 (due to derivative constraints, we cannot have indent > len/3)
84 w -> inf, G (w) -> 2*h_inf
86 i.e.
89 G (0) = 0 , G'(0) 1/3, G (infty) = 2h_inf
91 solve from
93 G (w) = r + p/(w+q)
95 yields
97 G (w) = 2 h_inf - max_fraction * q^2/ (w + q)
99 with q = 2 h_inf
102 void
103 get_slur_indent_height (Real *indent, Real *height,
104 Real width, Real h_inf, Real r_0)
106 Real max_fraction = 1.0 / 3.1;
107 *height = slur_height (width, h_inf, r_0);
109 Real q = 2 * h_inf / max_fraction;
110 *indent = 2 * h_inf - sqr (q) * max_fraction / (width + q);
113 Bezier
114 slur_shape (Real width, Real h_inf, Real r_0)
116 Real indent;
117 Real height;
119 get_slur_indent_height (&indent, &height,
120 width, h_inf, r_0);
122 Bezier curve;
123 curve.control_[0] = Offset (0, 0);
124 curve.control_[1] = Offset (indent, height);
125 curve.control_[2] = Offset (width - indent, height);
126 curve.control_[3] = Offset (width, 0);
127 return curve;