]> git.donarmstrong.com Git - lilypond.git/blob - lily/bezier.cc
release: 0.1.56
[lilypond.git] / lily / bezier.cc
1 /*
2   bezier.cc -- implement Bezier and Bezier_bow
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1998 Jan Nieuwenhuizen <jan@digicash.com>
7 */
8
9 #include <math.h>
10 #include "offset.hh"
11 #include "bezier.hh"
12 #include "dimen.hh"
13 #include "paper-def.hh"
14
15 Bezier::Bezier (int steps_i)
16 {
17   steps_i_ = steps_i;
18   curve_ = new Offset [steps_i_ + 1];
19 }
20
21 Bezier::~Bezier ()
22 {
23   delete[] curve_;
24 }
25
26 //from GNU gs3.33: ega.c
27 void
28 Bezier::calc (Offset control[4])
29 {       
30   Real dt = 1.0 / steps_i_;
31   Real cx = 3.0 * (control[1].x() - control[0].x());
32   Real bx = 3.0 * (control[2].x() - control[1].x()) - cx;
33   Real ax = control[3].x() - (control[0].x() + cx + bx);
34   Real cy = 3.0 * (control[1].y () - control[0].y ());
35   Real by = 3.0 * (control[2].y () - control[1].y ()) - cy; 
36   Real ay = control[3].y () - (control[0].y () + cy + by);
37   Real t = 0.0;
38   int i = 0;
39   while ( t <= 1.0 )
40     {    
41       curve_[i].x() = ((ax * t + bx) * t + cx) * t + control[0].x();
42       curve_[i++].y () = ((ay * t + by) * t + cy) * t + control[0].y ();
43       t += dt;
44     }
45 }
46
47 Real
48 Bezier::y (Real x)
49 {
50   if (x <= curve_[0].x())
51     return curve_[0].y ();
52   for (int i = 1; i < steps_i_; i++ )
53     {
54       if (x < curve_[i].x())
55         {
56           Real lin = (x - curve_[i-1].x()) / (curve_[i].x() - curve_[i-1].x());
57           return curve_[i-1].y () + lin * (curve_[i].y () - curve_[i-1].y ());
58         }
59     }
60   return curve_[steps_i_-1].y ();
61 }
62
63
64 Bezier_bow::Bezier_bow (Paper_def* paper_l)
65   : Bezier(10)
66 {
67   paper_l_ = paper_l;
68 }
69
70
71 /* 
72   from feta-sleur.ly
73
74         slurheightlimit#:=staffsize#/2;
75         sluralpha:=slurheightlimit#*pi/2;
76         % slurratio:=1/3;
77         slurratio:=0.3333;
78         slurbeta:=3/4*pi*slurratio/sluralpha;
79
80         b#:=length(dx#,dy#);
81         % ugh: huh? 2/5
82         indent#:=2/5*sluralpha*atan(slurbeta*b#);
83         height:=(indent+h)*d;
84         z1=(0,0);
85         z2=(b,0);
86         z3=(indent,height);
87         z4=(b-indent,height);
88
89         boogje:=boogje rotated angle(dxs,dys);
90 */
91
92 void
93 Bezier_bow::calc (Real dx, Real dy, Real h, Real d)
94 {
95   // ugh
96   Real pi = M_PI;
97   // ugh
98   Real staffsize_f = paper_l_->get_var ("barsize");
99   Real height_limit = staffsize_f;
100   Real alpha = height_limit * pi / 2.0;
101   Real ratio = 1.0/3.0;
102   Real beta = 3.0/4.0 * pi * ratio/alpha;
103
104   Real b = sqrt (dx * dx + dy * dy);
105   Real indent = 2.0/5.0 * alpha * atan (beta * b);
106   // ugh, ugly height hack, see lily-ps-defs.tex
107   Real height = (indent + h) * d;
108  
109   Offset control[4];
110   control[0] = Offset(0, 0);
111   control[1] = Offset(indent, height);
112   control[2] = Offset(b - indent, height);
113   control[3] = Offset( b, 0 );
114  
115   Real phi = dx ? atan (dy/dx) : sign (dy) * pi / 2.0;
116   Real sphi = sin (phi);
117   Real cphi = cos (phi);
118   for (int i = 1; i < 4; i++)
119     {
120       control[i].x() = cphi * control[i].x() - sphi * control[i].y ();
121       control[i].y () = sphi * control[i].x() + cphi * control[i].y ();
122     }
123   Bezier::calc (control);
124 }
125