2 collision.cc -- implement Collision
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "collision.hh"
10 #include "note-column.hh"
11 #include "note-head.hh"
12 #include "paper-def.hh"
14 Collision::Collision()
16 set_axes (X_AXIS
, Y_AXIS
);
20 Collision::add_column (Note_column
* ncol_l
)
22 clash_l_arr_
.push (ncol_l
);
24 add_dependency (ncol_l
);
28 /** This complicated routine moves note columns around horizontally to
29 ensure that notes don't clash.
31 This should be done better, probably.
37 Collision::do_pre_processing()
39 Drul_array
<Link_array
<Note_column
> > clash_groups
;
40 Drul_array
<Array
<int> > shifts
;
42 for (int i
=0; i
< clash_l_arr_
.size(); i
++)
44 clash_groups
[clash_l_arr_
[i
]->dir ()].push (clash_l_arr_
[i
]);
51 Array
<int> & shift (shifts
[d
]);
52 Link_array
<Note_column
> & clashes (clash_groups
[d
]);
54 clashes
.sort (Note_column::shift_compare
);
56 for (int i
=0; i
< clashes
.size (); i
++)
59 = clashes
[i
]->remove_elt_property (horizontal_shift_scm_sym
);
64 shift
.push (gh_scm2int (SCM_CDR (sh
)));
67 for (int i
=1; i
< shift
.size (); i
++)
69 if (shift
[i
-1] == shift
[i
])
71 warning (_ ("Too many clashing notecolumns. Ignoring them."));
76 while ((flip (&d
))!= UP
);
78 Drul_array
< Array
< Slice
> > extents
;
79 Drul_array
< Array
< Real
> > offsets
;
83 for (int i
=0; i
< clash_groups
[d
].size (); i
++)
85 Slice
s(clash_groups
[d
][i
]->head_positions_interval ());
89 offsets
[d
].push (d
* 0.5 * i
);
92 while ((flip (&d
))!= UP
);
96 for (int i
=1; i
< clash_groups
[d
].size (); i
++)
98 Slice prev
=extents
[d
][i
-1];
99 prev
.intersect (extents
[d
][i
]);
100 if (prev
.length ()> 0 ||
101 (extents
[-d
].size () && d
* (extents
[d
][i
][-d
] - extents
[-d
][0][d
]) < 0))
102 for (int j
= i
; j
< clash_groups
[d
].size (); j
++)
103 offsets
[d
][j
] += d
* 0.5;
106 while ((flip (&d
))!= UP
);
109 if the up and down version are close, and can not be merged, move
110 all of them again. */
111 if (extents
[UP
].size () && extents
[DOWN
].size ())
113 Note_column
*cu_l
=clash_groups
[UP
][0];
114 Note_column
*cd_l
=clash_groups
[DOWN
][0];
115 Note_head
* nu_l
= cu_l
->head_l_arr_
[0];
116 Note_head
* nd_l
= cd_l
->head_l_arr_
.top();
117 int downpos
= cd_l
->head_positions_interval ()[SMALLER
];
118 int uppos
= cu_l
->head_positions_interval ()[BIGGER
];
122 && nu_l
->balltype_i_
== nd_l
->balltype_i_
123 && nu_l
->dots_i_
== nd_l
->dots_i_
;
126 notes are close, but can not be merged. Shift
128 if (abs(uppos
- downpos
) < 2 && !merge
)
131 for (int i
=0; i
< clash_groups
[d
].size (); i
++)
133 offsets
[d
][i
] -= d
* 0.5;
136 while ((flip (&d
))!= UP
);
139 Real wid_f
= paper_l ()->note_width ();
142 for (int i
=0; i
< clash_groups
[d
].size (); i
++)
144 clash_groups
[d
][i
]->translate_axis (offsets
[d
][i
]*wid_f
, X_AXIS
);
147 while (flip (&d
) != UP
);
152 Collision::do_substitute_element_pointer (Score_element
*o_l
,Score_element
*n_l
)
156 clash_l_arr_
.substitute (dynamic_cast<Note_column
*> (o_l
),
157 dynamic_cast <Note_column
*> (n_l
));