]> git.donarmstrong.com Git - lilypond.git/blob - src/beam.cc
release: 0.0.10
[lilypond.git] / src / beam.cc
1 #include "beam.hh"
2 #include "debug.hh"
3 #include "symbol.hh"
4 #include "molecule.hh"
5 #include "leastsquares.hh"
6 #include "pcol.hh"
7 #include "stem.hh"
8 #include "paper.hh"
9 #include "lookup.hh"
10
11
12 struct Stem_info {
13     Real x;
14     Real idealy;
15     Real miny;
16     int no_beams;
17
18     ///////////////
19     
20     Stem_info(){}
21     Stem_info(const Stem*);
22 };
23 Stem_info::Stem_info(const Stem*s)
24 {
25     x = s->hpos();
26     int dir = s->dir;
27     idealy  = MAX(dir*s->top, dir*s->bot);
28     miny = MAX(dir*s->minnote, dir*s-> maxnote);
29     assert(miny <= idealy);
30     no_beams = s->flag;
31 }
32
33 /****************/
34
35 Beam::Beam()
36 {
37     slope = 0;
38     left_pos = 0.0;
39     dir =0;
40 }
41
42 void
43 Beam::add(Stem*s)
44 {
45     stems.bottom().add(s);
46     s->print_flag = false;
47 }
48
49 void
50 Beam::set_default_dir()
51 {
52     int dirs[2];
53     dirs[0]=0; dirs[1] =0;
54     for (PCursor<Stem*> sc(stems); sc.ok(); sc++) {
55         sc->set_default_dir();
56         dirs[(sc->dir+1)/2] ++;
57     }
58     dir =  (dirs[0] > dirs[1]) ? -1 : 1;
59     for (PCursor<Stem*> sc(stems); sc.ok(); sc++) {
60         sc->dir = dir;
61     }
62 }
63 /*
64   should use minimum energy formulation (cf linespacing)
65   */
66 void
67 Beam::solve_slope()
68 {
69     svec<Stem_info> sinfo;
70     for (PCursor<Stem* >sc(stems); sc.ok(); sc++) {
71         sc->set_default_extents();
72         Stem_info i(sc);
73         sinfo.add(i);
74     }
75     Real leftx = sinfo[0].x;
76     Least_squares l;
77     for (int i=0; i < sinfo.sz(); i++) {
78         sinfo[i].x -= leftx;
79         l.input.add(Offset(sinfo[i].x, sinfo[i].idealy));
80     }
81
82     l.minimise(slope, left_pos);
83     Real dy = 0.0;
84     for (int i=0; i < sinfo.sz(); i++) {
85         Real y = sinfo[i].x * slope + left_pos;
86         Real my = sinfo[i].miny;
87
88         if (my - y > dy)
89             dy = my -y; 
90     }
91     left_pos += dy;
92     left_pos *= dir;    
93     slope *= dir;
94     
95     {
96         Real inter =paper()->interline()/2;
97         Real unitslope = slope*inter;
98
99         // set beamslope, for setting stems correctly
100         // ignoring return.
101         Symbol sy = paper()->lookup_->beam(unitslope, width().length());
102         slope =unitslope / inter;
103     }
104 }
105
106 void
107 Beam::set_stemlens()
108 {
109     PCursor<Stem*> s(stems);
110     Real x0 = s->hpos();    
111     for (; s.ok() ; s++) {
112         Real x =  s->hpos()-x0;
113         s->set_stemend(left_pos + slope * x);   
114     }
115 }
116
117 void
118 Beam::calculate()
119 {
120     assert(stems.size()>1);
121     if (!dir)
122         set_default_dir();
123
124     solve_slope();
125     set_stemlens();
126 }
127
128 void
129 Beam::process()
130 {
131     calculate();
132     brew_molecule();
133 }
134
135
136 // todo.
137 Spanner *
138 Beam::broken_at(const PCol *, const PCol *) const
139 {
140     return new Beam(*this);
141 }
142
143 void
144 Beam::preprocess()
145 {
146     left  = (*stems.top())   ->pcol_;
147     right = (*stems.bottom())->pcol_;    
148 }
149
150 Interval
151 Beam::height() const
152 {
153     return output->extent().y;
154 }
155
156 Interval
157 Beam::width() const
158 {
159     Beam * me = (Beam*) this;   // ugh
160     return Interval( (*me->stems.top()) ->hpos(),
161                      (*me->stems.bottom()) ->hpos() );
162 }
163
164 void
165 Beam::brew_molecule()
166 {
167     Real inter=paper()->interline()/2;
168     Real sl = slope*inter;
169     Real w =  width().length() + paper()->rule_thickness();
170     Symbol s = paper()->lookup_->beam(sl,w);
171
172     Atom a(s);
173     
174     Real dx = width().min -left->hpos;
175     a.translate(Offset(dx,left_pos*inter));
176     output = new Molecule(a);
177 }
178
179 void
180 Beam::print()const
181 {
182     mtor << "Beam, slope " <<slope << "left ypos " << left_pos<<'\n';    
183 }
184