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