Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 /* | 1 /* |
2 This file is part of LilyPond, the GNU music typesetter. | 2 This file is part of LilyPond, the GNU music typesetter. |
3 | 3 |
4 Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl> |
5 Jan Nieuwenhuizen <janneke@gnu.org> | 5 Jan Nieuwenhuizen <janneke@gnu.org> |
6 | 6 |
7 LilyPond is free software: you can redistribute it and/or modify | 7 LilyPond is free software: you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
9 the Free Software Foundation, either version 3 of the License, or | 9 the Free Software Foundation, either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
174 c.beam_y_.widen (0.5 * beam_thickness_); | 174 c.beam_y_.widen (0.5 * beam_thickness_); |
175 | 175 |
176 c.x_ = x; | 176 c.x_ = x; |
177 | 177 |
178 y *= 1 / staff_space_; | 178 y *= 1 / staff_space_; |
179 c.y_ = y; | 179 c.y_ = y; |
180 c.base_penalty_ = score_factor; | 180 c.base_penalty_ = score_factor; |
181 collisions_.push_back (c); | 181 collisions_.push_back (c); |
182 } | 182 } |
183 | 183 |
184 void Beam_scoring_problem::init_instance_variables () | 184 void Beam_scoring_problem::init_instance_variables (Grob *me, Drul_array<Real> y s, bool align_broken_intos) |
Keith
2011/11/01 04:19:30
Logically, this is part of the constructor.
If you
| |
185 { | 185 { |
186 beam_ = dynamic_cast<Spanner *> (me); | |
187 unquanted_y_ = ys; | |
188 | |
189 /* | |
190 If 'ys' are finite, use them as starting points for y-positions of the | |
191 ends of the beam, instead of the best-fit through the natural ends of | |
192 the stems. Otherwise, we want to do initial slope calculations. | |
193 */ | |
194 do_initial_slope_calculations_ = false; | |
195 Direction d = LEFT; | |
196 do | |
197 do_initial_slope_calculations_ |= isinf (unquanted_y_[d]) || isnan (unquante d_y_[d]); | |
198 while (flip (&d) != LEFT); | |
199 | |
200 /* | |
201 Calculations are relative to a unit-scaled staff, i.e. the quants are | |
202 divided by the current staff_space_. | |
203 */ | |
204 staff_space_ = Staff_symbol_referencer::staff_space (beam_); | |
205 beam_thickness_ = Beam::get_beam_thickness (beam_) / staff_space_; | |
206 line_thickness_ = Staff_symbol_referencer::line_thickness (beam_) / staff_spac e_; | |
207 | |
208 // This is the least-squares DY, corrected for concave beams. | |
209 musical_dy_ = robust_scm2double (beam_->get_property ("least-squares-dy"), 0); | |
210 | |
186 vector<Spanner *> beams; | 211 vector<Spanner *> beams; |
187 if (consistent_broken_slope_) | 212 align_broken_intos_ = align_broken_intos; |
213 if (align_broken_intos_) | |
188 { | 214 { |
189 Spanner *orig = dynamic_cast<Spanner *> (beam_->original ()); | 215 Spanner *orig = dynamic_cast<Spanner *> (beam_->original ()); |
190 if (!orig) | 216 if (!orig) |
191 consistent_broken_slope_ = false; | 217 align_broken_intos_ = false; |
Keith
2011/11/01 04:19:30
Can you make these tests and adjust the value of t
| |
192 else if (!orig->broken_intos_.size ()) | 218 else if (!orig->broken_intos_.size ()) |
193 consistent_broken_slope_ = false; | 219 align_broken_intos_ = false; |
194 else | 220 else |
195 beams.insert (beams.end (), orig->broken_intos_.begin (), orig->broken_i ntos_.end ()); | 221 beams.insert (beams.end (), orig->broken_intos_.begin (), orig->broken_i ntos_.end ()); |
196 } | 222 } |
197 if (!consistent_broken_slope_) | 223 if (!align_broken_intos_) |
198 beams.push_back (beam_); | 224 beams.push_back (beam_); |
199 | 225 |
226 /* | |
227 x_span_ is a single scalar, cumulatively summing the length of all the | |
228 segments the parent beam was broken-into. | |
229 */ | |
200 x_span_ = 0.0; | 230 x_span_ = 0.0; |
Keith
2011/11/01 04:19:30
x_span_ is a single scalar, cumulatively summing t
| |
231 is_knee_ = false; | |
201 normal_stem_count_ = 0; | 232 normal_stem_count_ = 0; |
202 for (vsize i = 0; i < beams.size (); i++) | 233 for (vsize i = 0; i < beams.size (); i++) |
203 { | 234 { |
204 Interval local_x_span; | |
205 extract_grob_set (beams[i], "stems", stems); | 235 extract_grob_set (beams[i], "stems", stems); |
206 extract_grob_set (beams[i], "covered-grobs", fake_collisions); | 236 extract_grob_set (beams[i], "covered-grobs", fake_collisions); |
207 vector<Grob *> collisions; | 237 vector<Grob *> collisions; |
208 | 238 |
209 for (vsize j = 0; j < fake_collisions.size (); j++) | 239 for (vsize j = 0; j < fake_collisions.size (); j++) |
210 if (fake_collisions[j]->get_system () == beams[i]->get_system ()) | 240 if (fake_collisions[j]->get_system () == beams[i]->get_system ()) |
211 collisions.push_back (fake_collisions[j]); | 241 collisions.push_back (fake_collisions[j]); |
212 | 242 |
213 Grob *common[2]; | 243 Grob *common[2]; |
214 for (int a = 2; a--;) | 244 for (int a = 2; a--;) |
215 common[a] = common_refpoint_of_array (stems, beams[i], Axis (a)); | 245 common[a] = common_refpoint_of_array (stems, beams[i], Axis (a)); |
Keith
2011/11/01 04:19:30
Looks like one of these will be overwritten in the
| |
216 ······ | 246 ······ |
217 Direction d = LEFT; | 247 Direction d = LEFT; |
218 do | 248 do |
219 common[X_AXIS] = beams[i]->get_bound (d)->common_refpoint (common[X_AXIS ], X_AXIS); | 249 common[X_AXIS] = beams[i]->get_bound (d)->common_refpoint (common[X_AXIS ], X_AXIS); |
220 while (flip (&d) != LEFT); | 250 while (flip (&d) != LEFT); |
221 | 251 |
222 const Interval x_pos = robust_scm2interval (beams[i]->get_property ("X-pos itions"), Interval (0.0, 0.0)); | 252 // positions of the endpoints of this beam segment, including any overhang s |
Keith
2011/11/01 04:19:30
positions of the endpoints of this beam segment, i
| |
253 const Interval x_pos = robust_scm2interval (beams[i]->get_property ("X-pos itions"), | |
254 Interval (0.0, 0.0)); | |
223 | 255 |
224 Drul_array<Grob *> edge_stems (Beam::first_normal_stem (beams[i]), | 256 Drul_array<Grob *> edge_stems (Beam::first_normal_stem (beams[i]), |
225 Beam::last_normal_stem (beams[i])); | 257 Beam::last_normal_stem (beams[i])); |
226 d = LEFT; | |
227 do | |
228 local_x_span[d] = edge_stems[d] ? edge_stems[d]->relative_coordinate (co mmon[X_AXIS], X_AXIS) : 0.0; | |
Keith
2011/11/01 04:19:30
So local_x_span includes *only* the portion with n
| |
229 while (flip (&d) != LEFT); | |
230 | 258 |
231 Drul_array<bool> dirs_found (0, 0); | 259 Drul_array<bool> dirs_found (0, 0); |
232 | 260 |
233 Real my_y = beams[i]->relative_coordinate (common[Y_AXIS], Y_AXIS); | 261 Real my_y = beams[i]->relative_coordinate (common[Y_AXIS], Y_AXIS); |
234 | 262 |
235 Interval beam_width (-1.0,-1.0); | 263 Interval beam_width (-1.0,-1.0); |
236 for (vsize j = 0; j < stems.size (); j++) | 264 for (vsize j = 0; j < stems.size (); j++) |
237 { | 265 { |
238 Grob *s = stems[j]; | 266 Grob *s = stems[j]; |
239 beam_multiplicity_.push_back (Stem::beam_multiplicity (stems[j])); | 267 beam_multiplicity_.push_back (Stem::beam_multiplicity (stems[j])); |
240 head_positions_.push_back (Stem::head_positions (stems[j])); | 268 head_positions_.push_back (Stem::head_positions (stems[j])); |
241 is_normal_.push_back (Stem::is_normal_stem (stems[j])); | 269 is_normal_.push_back (Stem::is_normal_stem (stems[j])); |
242 | 270 |
243 Stem_info si (Stem::get_stem_info (s)); | 271 Stem_info si (Stem::get_stem_info (s)); |
244 si.scale (1 / staff_space_); | 272 si.scale (1 / staff_space_); |
245 stem_infos_.push_back (si); | 273 stem_infos_.push_back (si); |
246 chord_start_y_.push_back (Stem::chord_start_y (s)); | 274 chord_start_y_.push_back (Stem::chord_start_y (s)); |
247 dirs_found[si.dir_] = true; | 275 dirs_found[si.dir_] = true; |
248 | 276 |
249 bool f = to_boolean (s->get_property ("french-beaming")) | 277 bool f = to_boolean (s->get_property ("french-beaming")) |
250 && s != edge_stems[LEFT] && s != edge_stems[RIGHT]; | 278 && s != edge_stems[LEFT] && s != edge_stems[RIGHT]; |
251 | 279 |
252 Real y = Beam::calc_stem_y (beams[i], s, common, local_x_span[LEFT], l ocal_x_span[RIGHT], CENTER, | 280 Real y = Beam::calc_stem_y (beams[i], s, common, x_pos[LEFT], x_pos[RI GHT], CENTER, |
253 Interval (0, 0), f); | 281 Interval (0, 0), f); |
254 base_lengths_.push_back (y / staff_space_); | 282 base_lengths_.push_back (y / staff_space_); |
255 stem_xpositions_.push_back (s->relative_coordinate (common[X_AXIS], X_ AXIS) - x_pos[LEFT] + x_span_); | 283 stem_xpositions_.push_back (s->relative_coordinate (common[X_AXIS], X_ AXIS) - x_pos[LEFT] + x_span_); |
256 stem_ypositions_.push_back (s->relative_coordinate (common[Y_AXIS], Y_ AXIS) - my_y); | 284 stem_ypositions_.push_back (s->relative_coordinate (common[Y_AXIS], Y_ AXIS) - my_y); |
257 if (is_normal_.back ()) | 285 if (is_normal_.back ()) |
258 { | 286 { |
259 if (beam_width[LEFT] == -1.0) | 287 if (beam_width[LEFT] == -1.0) |
260 beam_width[LEFT] = stem_xpositions_.back (); | 288 beam_width[LEFT] = stem_xpositions_.back (); |
261 beam_width[RIGHT] = stem_xpositions_.back (); | 289 beam_width[RIGHT] = stem_xpositions_.back (); |
262 } | 290 } |
263 } | 291 } |
264 | 292 |
265 edge_dirs_ = Drul_array<Direction> (CENTER, CENTER); | 293 edge_dirs_ = Drul_array<Direction> (CENTER, CENTER); |
266 normal_stem_count_ += Beam::normal_stem_count (beams[i]); | 294 normal_stem_count_ += Beam::normal_stem_count (beams[i]); |
267 if (normal_stem_count_) | 295 if (normal_stem_count_) |
268 edge_dirs_ = Drul_array<Direction> (stem_infos_[0].dir_, | 296 edge_dirs_ = Drul_array<Direction> (stem_infos_[0].dir_, |
269 stem_infos_.back ().dir_); | 297 stem_infos_.back ().dir_); |
270 | 298 |
271 is_xstaff_ = Align_interface::has_interface (common[Y_AXIS]); | 299 is_xstaff_ = Align_interface::has_interface (common[Y_AXIS]); |
272 is_knee_ = dirs_found[LEFT] && dirs_found[RIGHT]; | 300 is_knee_ |= dirs_found[DOWN] && dirs_found[UP]; |
Keith
2011/11/01 04:19:30
Why not UP and DOWN?
Are we still in the loop over
| |
273 | 301 |
274 staff_radius_ = Staff_symbol_referencer::staff_radius (beams[i]); | 302 staff_radius_ = Staff_symbol_referencer::staff_radius (beams[i]); |
275 edge_beam_counts_ = Drul_array<int> | 303 edge_beam_counts_ = Drul_array<int> |
276 (Stem::beam_multiplicity (stems[0]).length () + 1, | 304 (Stem::beam_multiplicity (stems[0]).length () + 1, |
277 Stem::beam_multiplicity (stems.back ()).length () + 1) ; | 305 Stem::beam_multiplicity (stems.back ()).length () + 1) ; |
278 | 306 |
279 // TODO - why are we dividing by staff_space_? | 307 // TODO - why are we dividing by staff_space_? |
280 beam_translation_ = Beam::get_beam_translation (beams[i]) / staff_space_; | 308 beam_translation_ = Beam::get_beam_translation (beams[i]) / staff_space_; |
281 | 309 |
282 d = LEFT; | 310 d = LEFT; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
345 Interval y; | 373 Interval y; |
346 y.set_full (); | 374 y.set_full (); |
347 y[-stem_dir] = Stem::chord_start_y (*it) + (*it)->relative_coordinate (common[Y_AXIS], Y_AXIS) | 375 y[-stem_dir] = Stem::chord_start_y (*it) + (*it)->relative_coordinate (common[Y_AXIS], Y_AXIS) |
348 - beams[i]->relative_coordinate (common[Y_AXIS], Y_AXIS ); | 376 - beams[i]->relative_coordinate (common[Y_AXIS], Y_AXIS ); |
349 | 377 |
350 Real factor = parameters_.STEM_COLLISION_FACTOR; | 378 Real factor = parameters_.STEM_COLLISION_FACTOR; |
351 if (!unsmob_grob (s->get_object ("beam"))) | 379 if (!unsmob_grob (s->get_object ("beam"))) |
352 factor = 1.0; | 380 factor = 1.0; |
353 add_collision (x, y, factor); | 381 add_collision (x, y, factor); |
354 } | 382 } |
355 x_span_ += beams[i]->spanner_length (); | 383 x_span_ += beams[i]->spanner_length (); |
Keith
2011/11/01 04:19:30
Ultimately from Beam::calc_x_positions(), so x_spa
| |
356 } | 384 } |
357 } | 385 } |
358 | 386 |
359 Beam_scoring_problem::Beam_scoring_problem (Grob *me, Drul_array<Real> ys, bool consistent_broken_slope) | 387 Beam_scoring_problem::Beam_scoring_problem (Grob *me, Drul_array<Real> ys, bool align_broken_intos) |
Keith
2011/11/01 04:19:30
If 'ys' are finite, use them as starting points fo
| |
360 { | 388 { |
361 beam_ = dynamic_cast<Spanner *> (me); | 389 beam_ = dynamic_cast<Spanner *> (me); |
362 unquanted_y_ = ys; | 390 unquanted_y_ = ys; |
363 consistent_broken_slope_ = consistent_broken_slope; | 391 align_broken_intos_ = align_broken_intos; |
364 do_initial_slope_calculations_ = false; | |
365 Direction d = LEFT; | |
366 do | |
367 do_initial_slope_calculations_ |= isinf (ys[d]) || isnan (ys[d]); | |
368 while (flip (&d) != LEFT); | |
369 | |
370 /* | |
371 Calculations are relative to a unit-scaled staff, i.e. the quants are | |
372 divided by the current staff_space_. | |
373 */ | |
374 staff_space_ = Staff_symbol_referencer::staff_space (me); | |
375 beam_thickness_ = Beam::get_beam_thickness (me) / staff_space_; | |
376 line_thickness_ = Staff_symbol_referencer::line_thickness (me) / staff_space_; | |
377 | |
378 // This is the least-squares DY, corrected for concave beams. | |
379 musical_dy_ = robust_scm2double (me->get_property ("least-squares-dy"), 0); | |
380 | 392 |
381 parameters_.fill (me); | 393 parameters_.fill (me); |
382 init_instance_variables (); | 394 init_instance_variables (me, ys, align_broken_intos); |
383 if (do_initial_slope_calculations_) | 395 if (do_initial_slope_calculations_) |
384 { | 396 { |
385 least_squares_positions (); | 397 least_squares_positions (); |
386 slope_damping (); | 398 slope_damping (); |
387 shift_region_to_valid (); | 399 shift_region_to_valid (); |
388 } | 400 } |
389 } | 401 } |
390 | 402 |
391 // Assuming V is not empty, pick a 'reasonable' point inside V. | 403 // Assuming V is not empty, pick a 'reasonable' point inside V. |
392 static Real | 404 static Real |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 set_minimum_dy (beam_, &dy); | 557 set_minimum_dy (beam_, &dy); |
546 | 558 |
547 ldy = dy; | 559 ldy = dy; |
548 unquanted_y_ = Interval (y, (y + dy)); | 560 unquanted_y_ = Interval (y, (y + dy)); |
549 } | 561 } |
550 | 562 |
551 musical_dy_ = ldy; | 563 musical_dy_ = ldy; |
552 beam_->set_property ("least-squares-dy", scm_from_double (musical_dy_)); | 564 beam_->set_property ("least-squares-dy", scm_from_double (musical_dy_)); |
553 } | 565 } |
554 | 566 |
567 /* | |
568 Determine whether a beam is concave. | |
569 | |
570 A beam is concave when the middle notes get closer to the | |
571 beam than the left and right edge notes. | |
572 | |
573 This is determined in two ways: by looking at the positions of the | |
574 middle notes, or by looking at the deviation of the inside notes | |
575 compared to the line connecting first and last. | |
576 | |
577 The tricky thing is what to do with beams with chords. There are no | |
578 real guidelines in this case. | |
579 */ | |
580 | |
581 bool | |
582 is_concave_single_notes (vector<int> const &positions, Direction beam_dir) | |
583 { | |
584 Interval covering; | |
585 covering.add_point (positions[0]); | |
586 covering.add_point (positions.back ()); | |
587 | |
588 bool above = false; | |
589 bool below = false; | |
590 bool concave = false; | |
591 | |
592 /* | |
593 notes above and below the interval covered by 1st and last note. | |
594 */ | |
595 for (vsize i = 1; i + 1 < positions.size (); i++) | |
596 { | |
597 above = above || (positions[i] > covering[UP]); | |
598 below = below || (positions[i] < covering[DOWN]); | |
599 } | |
600 | |
601 concave = concave || (above && below); | |
602 /* | |
603 A note as close or closer to the beam than begin and end, but the | |
604 note is reached in the opposite direction as the last-first dy | |
605 */ | |
606 int dy = positions.back () - positions[0]; | |
607 int closest = max (beam_dir * positions.back (), beam_dir * positions[0]); | |
608 for (vsize i = 2; !concave && i + 1 < positions.size (); i++) | |
609 { | |
610 int inner_dy = positions[i] - positions[i - 1]; | |
611 if (sign (inner_dy) != sign (dy) | |
612 && (beam_dir * positions[i] >= closest | |
613 || beam_dir * positions[i - 1] >= closest)) | |
614 concave = true; | |
615 } | |
616 | |
617 bool all_closer = true; | |
618 for (vsize i = 1; all_closer && i + 1 < positions.size (); i++) | |
619 { | |
620 all_closer = all_closer | |
621 && (beam_dir * positions[i] > closest); | |
622 } | |
623 | |
624 concave = concave || all_closer; | |
625 return concave; | |
626 } | |
627 | |
628 Real | |
629 calc_positions_concaveness (vector<int> const &positions, Direction beam_dir) | |
630 { | |
631 Real dy = positions.back () - positions[0]; | |
632 Real slope = dy / Real (positions.size () - 1); | |
633 Real concaveness = 0.0; | |
634 for (vsize i = 1; i + 1 < positions.size (); i++) | |
635 { | |
636 Real line_y = slope * i + positions[0]; | |
637 | |
638 concaveness += max (beam_dir * (positions[i] - line_y), 0.0); | |
639 } | |
640 | |
641 concaveness /= positions.size (); | |
642 | |
643 /* | |
644 Normalize. For dy = 0, the slope ends up as 0 anyway, so the | |
645 scaling of concaveness doesn't matter much. | |
646 */ | |
647 if (dy) | |
648 concaveness /= fabs (dy); | |
649 return concaveness; | |
650 } | |
651 | |
652 Real | |
653 Beam_scoring_problem::calc_concaveness () | |
654 { | |
655 SCM conc = beam_->get_property ("concaveness"); | |
656 if (scm_is_number (conc)) | |
657 return scm_to_double (conc); | |
658 | |
659 if (is_knee_) | |
660 return 0.0; | |
661 | |
662 Direction beam_dir = CENTER; | |
663 for (vsize i = is_normal_.size (); i--;) | |
664 if (is_normal_[i] && stem_infos_[i].dir_) | |
665 beam_dir = stem_infos_[i].dir_; | |
666 | |
667 if (normal_stem_count_ <= 2) | |
668 return 0.0; | |
669 | |
670 vector<int> close_positions; | |
671 vector<int> far_positions; | |
672 for (vsize i = 0; i < is_normal_.size (); i++) | |
673 if (is_normal_[i]) | |
674 { | |
675 /* | |
676 For chords, we take the note head that is closest to the beam. | |
677 | |
678 Hmmm.. wait, for the beams in the last measure of morgenlied, | |
679 this doesn't look so good. Let's try the heads farthest from | |
680 the beam. | |
681 */ | |
682 | |
683 close_positions.push_back ((int) rint (head_positions_[i][beam_dir])); | |
684 far_positions.push_back ((int) rint (head_positions_[i][-beam_dir])); | |
685 } | |
686 | |
687 Real concaveness = 0.0; | |
688 | |
689 if (is_concave_single_notes (beam_dir == UP ? close_positions : far_positions, beam_dir)) | |
690 { | |
691 concaveness = 10000; | |
692 } | |
693 else | |
694 { | |
695 concaveness = (calc_positions_concaveness (far_positions, beam_dir) | |
696 + calc_positions_concaveness (close_positions, beam_dir)) / 2; | |
697 } | |
698 | |
699 return concaveness; | |
700 } | |
701 | |
555 void | 702 void |
556 Beam_scoring_problem::slope_damping () | 703 Beam_scoring_problem::slope_damping () |
557 { | 704 { |
558 if (normal_stem_count_ <= 1) | 705 if (normal_stem_count_ <= 1) |
559 return; | 706 return; |
560 | 707 |
561 SCM s = beam_->get_property ("damping"); | 708 SCM s = beam_->get_property ("damping"); |
562 Real damping = scm_to_double (s); | 709 Real damping = scm_to_double (s); |
563 Real concaveness = robust_scm2double (beam_->get_property ("concaveness"), 0.0 ); | 710 Real concaveness = calc_concaveness (); |
564 if (concaveness >= 10000) | 711 if (concaveness >= 10000) |
565 { | 712 { |
566 unquanted_y_[LEFT] = unquanted_y_[RIGHT]; | 713 unquanted_y_[LEFT] = unquanted_y_[RIGHT]; |
567 musical_dy_ = 0; | 714 musical_dy_ = 0; |
568 damping = 0; | 715 damping = 0; |
569 } | 716 } |
570 | 717 |
571 if (damping) | 718 if (damping) |
572 { | 719 { |
573 Real dy = unquanted_y_[RIGHT] - unquanted_y_[LEFT]; | 720 Real dy = unquanted_y_[RIGHT] - unquanted_y_[LEFT]; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
733 | 880 |
734 unquanted_y_ = Drul_array<Real> (beam_left_y, (beam_left_y + beam_dy)); | 881 unquanted_y_ = Drul_array<Real> (beam_left_y, (beam_left_y + beam_dy)); |
735 } | 882 } |
736 | 883 |
737 void | 884 void |
738 Beam_scoring_problem::generate_quants (vector<Beam_configuration *> *scores) con st | 885 Beam_scoring_problem::generate_quants (vector<Beam_configuration *> *scores) con st |
739 { | 886 { |
740 int region_size = (int) parameters_.REGION_SIZE; | 887 int region_size = (int) parameters_.REGION_SIZE; |
741 | 888 |
742 // Knees and collisions are harder, lets try some more possibilities | 889 // Knees and collisions are harder, lets try some more possibilities |
743 if (do_initial_slope_calculations_) | 890 if (is_knee_) |
Keith
2011/11/01 04:19:30
Even if we made an earlier pass, and avoid the col
| |
744 { | 891 region_size += 2; |
745 if (is_knee_) | 892 if (collisions_.size ()) |
746 region_size += 2; | 893 region_size += 2; |
747 if (collisions_.size ()) | |
748 region_size += 2; | |
749 } | |
750 | 894 |
751 Real straddle = 0.0; | 895 Real straddle = 0.0; |
752 Real sit = (beam_thickness_ - line_thickness_) / 2; | 896 Real sit = (beam_thickness_ - line_thickness_) / 2; |
753 Real inter = 0.5; | 897 Real inter = 0.5; |
754 Real hang = 1.0 - (beam_thickness_ - line_thickness_) / 2; | 898 Real hang = 1.0 - (beam_thickness_ - line_thickness_) / 2; |
755 Real base_quants [] = {straddle, sit, inter, hang}; | 899 Real base_quants [] = {straddle, sit, inter, hang}; |
756 int num_base_quants = int (sizeof (base_quants) / sizeof (Real)); | 900 int num_base_quants = int (sizeof (base_quants) / sizeof (Real)); |
757 | 901 |
758 /* | 902 /* |
759 Asymetry ? should run to <= region_size ? | 903 Asymetry ? should run to <= region_size ? |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
921 if (configs[i]->done ()) | 1065 if (configs[i]->done ()) |
922 completed++; | 1066 completed++; |
923 } | 1067 } |
924 | 1068 |
925 string card = best->score_card_ + to_string (" c%d/%d", completed, configs .size ()); | 1069 string card = best->score_card_ + to_string (" c%d/%d", completed, configs .size ()); |
926 beam_->set_property ("annotation", ly_string2scm (card)); | 1070 beam_->set_property ("annotation", ly_string2scm (card)); |
927 } | 1071 } |
928 #endif | 1072 #endif |
929 | 1073 |
930 junk_pointers (configs); | 1074 junk_pointers (configs); |
931 if (consistent_broken_slope_) | 1075 if (align_broken_intos_) |
932 { | 1076 { |
933 Interval normalized_endpoints = robust_scm2interval (beam_->get_property ( "normalized-endpoints"), Interval (0, 1)); | 1077 Interval normalized_endpoints = robust_scm2interval (beam_->get_property ( "normalized-endpoints"), Interval (0, 1)); |
934 Real y_length = final_positions[RIGHT] - final_positions[LEFT]; | 1078 Real y_length = final_positions[RIGHT] - final_positions[LEFT]; |
935 | 1079 |
936 final_positions[LEFT] += normalized_endpoints[LEFT] * y_length; | 1080 final_positions[LEFT] += normalized_endpoints[LEFT] * y_length; |
937 final_positions[RIGHT] -= (1 - normalized_endpoints[RIGHT]) * y_length; | 1081 final_positions[RIGHT] -= (1 - normalized_endpoints[RIGHT]) * y_length; |
938 } | 1082 } |
939 | 1083 |
940 return final_positions; | 1084 return final_positions; |
941 } | 1085 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
979 } | 1123 } |
980 | 1124 |
981 /* Divide by number of stems, to make the measure scale-free. */ | 1125 /* Divide by number of stems, to make the measure scale-free. */ |
982 Direction d = DOWN; | 1126 Direction d = DOWN; |
983 do | 1127 do |
984 score[d] /= max (count[d], 1); | 1128 score[d] /= max (count[d], 1); |
985 while (flip (&d) != DOWN); | 1129 while (flip (&d) != DOWN); |
986 | 1130 |
987 /* | 1131 /* |
988 sometimes, two perfectly symmetric kneed beams will have the same score | 1132 sometimes, two perfectly symmetric kneed beams will have the same score |
989 and can either be quanted up or down. | 1133 and can either be quanted up or down. |
Keith
2011/11/01 04:19:30
Does this have something to do with X-extents, or
| |
990 ···· | 1134 ···· |
991 we choose the quanting in the direction of the slope so that the first stem | 1135 we choose the quanting in the direction of the slope so that the first stem |
992 always seems longer, reaching to the second, rather than squashed. | 1136 always seems longer, reaching to the second, rather than squashed. |
993 */ | 1137 */ |
994 if (is_knee_ && count[LEFT] == count[RIGHT] && count[LEFT] == 1 && unquanted_y _.delta ()) | 1138 if (is_knee_ && count[LEFT] == count[RIGHT] && count[LEFT] == 1 && unquanted_y _.delta ()) |
995 score[Direction (sign (unquanted_y_.delta ()))] += score[Direction (sign (un quanted_y_.delta ()))] < 1.0 ? 0.01 : 0.0; | 1139 score[Direction (sign (unquanted_y_.delta ()))] += score[Direction (sign (un quanted_y_.delta ()))] < 1.0 ? 0.01 : 0.0; |
996 | 1140 |
997 config->add (score[LEFT] + score[RIGHT], "L"); | 1141 config->add (score[LEFT] + score[RIGHT], "L"); |
998 } | 1142 } |
999 | 1143 |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1205 Real scale_free | 1349 Real scale_free |
1206 = max (parameters_.COLLISION_PADDING - dist, 0.0) / | 1350 = max (parameters_.COLLISION_PADDING - dist, 0.0) / |
1207 parameters_.COLLISION_PADDING; | 1351 parameters_.COLLISION_PADDING; |
1208 demerits | 1352 demerits |
1209 += collisions_[i].base_penalty_ * | 1353 += collisions_[i].base_penalty_ * |
1210 pow (scale_free, 3) * parameters_.COLLISION_PENALTY; | 1354 pow (scale_free, 3) * parameters_.COLLISION_PENALTY; |
1211 } | 1355 } |
1212 | 1356 |
1213 config->add (demerits, "C"); | 1357 config->add (demerits, "C"); |
1214 } | 1358 } |
LEFT | RIGHT |