2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2011--2012 Mike Solomon <mike@mikesolomon.org>
5 Jan Nieuwenhuizen <janneke@gnu.org>
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
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 LilyPond is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
21 #include "box-quarantine.hh"
24 Box_quarantine::Box_quarantine (Real padding, Axis a)
25 : padding_ (padding), a_ (a)
30 Box_quarantine::add_box_to_quarantine (Box infected)
33 nbox[a_].widen (padding_ / 2);
34 boxes_to_quarantine_.push_back (nbox);
38 Box_quarantine::quarantined_boxes ()
40 return boxes_to_quarantine_;
43 struct Intersection_info
48 Intersection_info (vsize index, Real amount, int mid);
51 Intersection_info::Intersection_info (vsize index, Real amount, int mid)
52 : index_ (index), amount_ (amount), mid_ (mid)
57 boxes_to_quarantine_ contains a vector of boxes that may
58 or may not overlap. it iterates through these boxes,
59 pushing quarantined_boxes_ epsilon over or epsilon under a
60 collision. when this type of change happens, the loop is marked
61 as "dirty" and re-iterated.
63 TODO: not sure if this loop causes infinite behavior...
67 sort_towards_middle(Intersection_info ii0, Intersection_info ii1)
69 // ugh...with C++11, we'll just be able to do a factory instead of
70 // bundling mid with the Intersection_info
72 assert ((double)(ii0.index_ - mid) >= 0.0);
73 assert ((double)(ii1.index_ - mid) >= 0.0);
74 return fabs (ii0.index_ - mid) < fabs (ii1.index_ - mid);
78 Box_quarantine::solve ()
80 int mid = boxes_to_quarantine_.size () / 2;
81 Real epsilon = 1.0e-4;
86 vector<Intersection_info> ii;
87 for (vsize i = 0; i < boxes_to_quarantine_.size () - 1; i++)
89 Box scratch (boxes_to_quarantine_[i]);
90 scratch.intersect (boxes_to_quarantine_[i + 1]);
91 if (!scratch.is_empty ())
92 ii.push_back (Intersection_info (i, scratch[a_].length (), mid));
94 vector_sort (ii, sort_towards_middle);
97 Offset shift (-(epsilon + ii[0].amount_ / 2.0), 0.0);
99 shift = shift.swapped ();
100 boxes_to_quarantine_[ii[0].index_].translate (shift);
101 shift[a_] = -shift[a_];
102 boxes_to_quarantine_[ii[0].index_ + 1].translate (shift);