9 #include "leastsquares.hh"
12 #include "paper-def.hh"
14 #include "grouping.hh"
26 Stem_info(const Stem
*);
29 Stem_info::Stem_info(const Stem
*s
)
33 idealy
= max(dir
*s
->top
, dir
*s
->bot
);
34 miny
= max(dir
*s
->minnote
, dir
*s
-> maxnote
);
35 assert(miny
<= idealy
);
44 assert(status
>= POSTCALCED
);
46 Real w
=(paper()->note_width() + width().length())/2.0;
47 return Offset(w
, (left_pos
+ w
* slope
)*paper()->internote());
60 stems
.bottom().add(s
);
61 s
->add_dependency(this);
62 s
->print_flag
= false;
66 Beam::set_default_dir()
69 dirs
[0]=0; dirs
[1] =0;
70 for (iter_top(stems
,i
); i
.ok(); i
++) {
71 int d
= i
->get_default_dir();
74 dir_i_
= (dirs
[0] > dirs
[1]) ? -1 : 1;
75 for (iter_top(stems
,i
); i
.ok(); i
++) {
81 should use minimum energy formulation (cf linespacing)
86 Array
<Stem_info
> sinfo
;
87 for (iter_top(stems
,i
); i
.ok(); i
++) {
88 i
->set_default_extents();
92 Real leftx
= sinfo
[0].x
;
94 for (int i
=0; i
< sinfo
.size(); i
++) {
96 l
.input
.push(Offset(sinfo
[i
].x
, sinfo
[i
].idealy
));
99 l
.minimise(slope
, left_pos
);
101 for (int i
=0; i
< sinfo
.size(); i
++) {
102 Real y
= sinfo
[i
].x
* slope
+ left_pos
;
103 Real my
= sinfo
[i
].miny
;
113 Real sl
= slope
*paper()->internote();
114 paper()->lookup_p_
->beam(sl
, 20 PT
);
115 slope
= sl
/paper()->internote();
122 Real x0
= s
->hindex();
123 for (; s
.ok() ; s
++) {
124 Real x
= s
->hindex()-x0
;
125 s
->set_stemend(left_pos
+ slope
* x
);
131 Beam::do_post_processing()
138 Beam::set_grouping(Rhythmic_grouping def
, Rhythmic_grouping cur
)
142 assert(cur
.children
.size() == stems
.size());
150 for (; s
.ok(); s
++) {
151 int f
= intlog2(abs(s
->flag
))-2;
156 b
= cur
.generate_beams(flags
, fi
);
159 assert(stems
.size() == b
.size()/2);
163 for (int i
=0; i
< b
.size() && s
.ok(); i
+=2, s
++) {
164 s
->beams_left
= b
[i
];
165 s
->beams_right
= b
[i
+1];
172 Beam::do_break_at( PCol
*, PCol
*) const
174 Beam
*beam_p
= new Beam(*this);
180 Beam::do_pre_processing()
182 left
= (*stems
.top()) ->pcol_l_
;
183 right
= (*stems
.bottom())->pcol_l_
;
184 assert(stems
.size()>1);
194 Beam
* me
= (Beam
*) this; // ugh
195 return Interval( (*me
->stems
.top()) ->hindex(),
196 (*me
->stems
.bottom()) ->hindex() );
200 beams to go with one stem.
203 Beam::stem_beams(Stem
*here
, Stem
*next
, Stem
*prev
)const
205 assert( !next
|| next
->hindex() > here
->hindex() );
206 assert( !prev
|| prev
->hindex() < here
->hindex() );
207 Real dy
=paper()->internote()*2;
208 Real stemdx
= paper()->rule_thickness();
209 Real sl
= slope
*paper()->internote();
210 paper()->lookup_p_
->beam(sl
, 20 PT
);
215 /* half beams extending to the left. */
217 int lhalfs
= lhalfs
= here
->beams_left
- prev
->beams_right
;
218 int lwholebeams
= here
->beams_left
<? prev
->beams_right
;
219 Real w
= (here
->hindex() - prev
->hindex())/4;
222 if (lhalfs
) // generates warnings if not
223 a
= paper()->lookup_p_
->beam(sl
, w
);
224 a
.translate(Offset (-w
, -w
* sl
));
225 for (int j
= 0; j
< lhalfs
; j
++) {
227 b
.translate(Offset(0, -dir_i_
* dy
* (lwholebeams
+j
)));
233 int rhalfs
= here
->beams_right
- next
->beams_left
;
234 int rwholebeams
= here
->beams_right
<? next
->beams_left
;
236 Real w
= next
->hindex() - here
->hindex();
237 Atom a
= paper()->lookup_p_
->beam(sl
, w
+ stemdx
);
240 for (; j
< rwholebeams
; j
++) {
242 b
.translate(Offset(0, -dir_i_
* dy
* j
));
248 a
= paper()->lookup_p_
->beam(sl
, w
);
250 for (; j
< rwholebeams
+ rhalfs
; j
++) {
252 b
.translate(Offset(0, -dir_i_
* dy
* j
));
257 leftbeams
.add(rightbeams
);
263 Beam::brew_molecule_p() const return out
;
265 Real inter
=paper()->internote();
267 Real x0
= stems
.top()->hindex();
269 for (iter_top(stems
,i
); i
.ok(); i
++) {
270 PCursor
<Stem
*> p(i
-1);
271 PCursor
<Stem
*> n(i
+1);
272 Stem
* prev
= p
.ok() ? p
.ptr() : 0;
273 Stem
* next
= n
.ok() ? n
.ptr() : 0;
275 Molecule sb
= stem_beams(i
, next
, prev
);
276 Real x
= i
->hindex()-x0
;
277 sb
.translate(Offset(x
, (x
* slope
+ left_pos
)* inter
));
280 out
->translate(Offset(x0
- left
->hpos
,0));
284 Beam::do_print()const
287 mtor
<< "slope " <<slope
<< "left ypos " << left_pos
;