source file of the GNU LilyPond music typesetter
- (c) 1996, 1997, 1998 Han-Wen Nienhuys <hanwen@stack.nl>
+ (c) 1996, 1997--1998, 1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
#include "spring-spacer.hh"
#include "p-col.hh"
#include "debug.hh"
+#include "dimensions.hh"
#include "qlp.hh"
#include "unionfind.hh"
#include "idealspacing.hh"
#include "pointer.tcc"
#include "score-column.hh"
#include "paper-def.hh"
-#include "dimen.hh"
#include "colhpos.hh"
-#include "main.hh" // experimental_fietsers
+#include "main.hh"
Vector
Spring_spacer::default_solution() const
Array<int> fixed;
for (PCursor<Idealspacing*> i (ideal_p_list_.top()); i.ok (); i++)
{
- connected.connect (i->left_i_,i->right_i_);
+ connected.connect (i->cols_drul_[LEFT],i->cols_drul_[RIGHT]);
}
for (int i = 0; i < cols_.size(); i++)
if (cols_[i].fixed_b())
{
if (! connected.equiv (fixed[0], i))
{
- warning (_("unconnected column: ") + String (i));
+ warning (_f ("unconnected column: %d", i));
loosen_column (i);
}
}
int right_rank = (j<sol_vec.dim()) ? cols_[j].rank_i_ : sol_vec.dim ();
int d_r = right_rank - left_rank;
- Colinfo loose=loose_col_arr_[k++];
+ Column_info loose=loose_col_arr_[k++];
int r = loose.rank_i_ ;
assert (r > left_rank && r < right_rank);
Real diff =v (other) - v (i) ;
if (COLFUDGE +diff < rods[j].distance_f_)
{
- DOUT << "i, other_i: " << i << " " << other << "\n";
- DOUT << "dist, minimal = " << diff <<" "
- << rods[j].distance_f_<<'\n';
+ DOUT << "i, other_i: " << i << " " << other << '\n';
+ DOUT << "dist, minimal = " << diff << " "
+ << rods[j].distance_f_ << '\n';
return false;
}
}
Vector v;
if (!try_initial_solution_and_tell (v))
{
- warning ("I'm too fat; call Oprah");
+ warning (_ ("I'm too fat; call Oprah"));
}
return v;
initsol (i)=cols_[i].fixed_position();
if (initsol (i) < min_x )
{
- DOUT << "failing: init, min : " << initsol (i) << " " << min_x << "\n";
+ DOUT << "failing: init, min : " << initsol (i) << " " << min_x << '\n';
initsol (i) = min_x;
succeeded = false;
}
for (PCursor<Idealspacing*> i (ideal_p_list_.top()); i.ok (); i++)
{
- int l = i->left_i_;
- int r = i->right_i_;
+ int l = i->cols_drul_[LEFT];
+ int r = i->cols_drul_[RIGHT];
quad (r,r) += i->hooke_f_;
quad (r,l) -= i->hooke_f_;
c += sqr (i->space_f_);
}
- // experimental
+
if (quad.dim() > 10)
quad.set_band();
Real e = 0.0;
for (PCursor<Idealspacing*> i (ideal_p_list_.top()); i.ok(); i++)
{
- e += i->energy_f(solution(i->right_i_) - solution(i->left_i_));
+ e += i->energy_f(solution(i->cols_drul_[RIGHT]) - solution(i->cols_drul_[LEFT]));
}
return e;
}
void
-Spring_spacer::lower_bound_solution (Col_hpositions*positions) const
+Spring_spacer::lower_bound_solution (Column_x_positions*positions) const
{
Mixed_qp lp (cols_.size());
make_matrices (lp.quad_,lp.lin_, lp.const_term_);
positions->satisfies_constraints_b_ = check_constraints (solution_vec);
}
-void
-Spring_spacer::solve (Col_hpositions*positions) const
+Spring_spacer::Spring_spacer ()
{
+ energy_normalisation_f_ = 1.0;
+}
+void
+Spring_spacer::solve (Column_x_positions*positions) const
+{
DOUT << "Spring_spacer::solve ()...";
- Vector solution_try;
+ Vector solution_try;
+
bool constraint_satisfaction = try_initial_solution_and_tell (solution_try);
if (constraint_satisfaction)
{
make_matrices (lp.quad_,lp.lin_, lp.const_term_);
make_constraints (lp);
set_fixed_cols (lp);
-
+
Vector solution_vec (lp.solve (solution_try));
-
+
positions->satisfies_constraints_b_ = check_constraints (solution_vec);
if (!positions->satisfies_constraints_b_)
{
- WARN << _("solution doesn't satisfy constraints.\n") ;
+ WARN << _ ("solution doesn't satisfy constraints") << '\n' ;
}
position_loose_cols (solution_vec);
positions->energy_f_ = calculate_energy_f (solution_vec);
{
positions->set_stupid_solution (solution_try);
}
+
DOUT << "Finished Spring_spacer::solve ()...";
}
void
Spring_spacer::add_column (Paper_column *col, bool fixed, Real fixpos)
{
- Colinfo c (col,(fixed)? &fixpos : 0);
+ Column_info c (col,(fixed)? &fixpos : 0);
int this_rank = cols_.size();
c.rank_i_ = this_rank;
void
Spring_spacer::loosen_column (int i)
{
- Colinfo c=cols_.get (i);
+ Column_info c=cols_.get (i);
for (PCursor<Idealspacing*> j (ideal_p_list_.top()); j.ok (); j++)
{
- if (j->left_i_ == i|| j->right_i_ == i)
+ if (j->cols_drul_[LEFT] == i|| j->cols_drul_[RIGHT] == i)
j.del();
else
j++;
#ifndef NPRINT
for (int i=0; i < cols_.size(); i++)
{
- DOUT << "col " << i<<' ';
+ DOUT << "col " << i << " ";
cols_[i].print();
}
for (PCursor<Idealspacing*> i (ideal_p_list_.top()); i.ok (); i++)
Idealspacing * s = new Idealspacing;
- s->left_i_ = i ;
- s->right_i_ = j;
+ s->cols_drul_[LEFT] = i ;
+ s->cols_drul_[RIGHT] = j;
s->space_f_ = d;
s->hooke_f_ = h;
/*
TODO: take out the refs to width
+
*/
/**
generate springs between columns.
- TODO: This needs rethinking. Spacing should take optical
+ TODO: This needs rethinking.......
+
+ * Spacing should take optical
effects into account
+ * Should be decentralised
+
The algorithm is taken from :
John S. Gourlay. ``Spacing a Line of Music,'' Technical Report
get_ruling_durations(shortest_playing_arr, context_shortest_arr);
Real interline_f = paper_l ()->interline_f ();
- Real nw_f = paper_l ()->note_width ();
- Array<Real> ideal_arr_;
- Array<Real> hooke_arr_;
+
+ Array<Real> ideal_arr;
+ Array<Real> hooke_arr;
for (int i=0; i < cols_.size() - 1; i++){
- ideal_arr_.push (-1.0);
- hooke_arr_.push (1.0);
+ ideal_arr.push (-1.0);
+ hooke_arr.push (1.0);
}
/*
{
Real symbol_distance =cols_[i].width_[RIGHT] + 2 PT;
Real durational_distance = 0;
-
-
Moment delta_t = scol_l (i+1)->when() - scol_l (i)->when () ;
- Real k= paper_l()->arithmetic_constant (context_shortest_arr[i]);
/*
ugh should use shortest_playing distance
*/
if (delta_t)
- durational_distance = paper_l()->duration_to_dist (delta_t,k);
+ {
+ Real k= paper_l()->arithmetic_constant (context_shortest_arr[i]);
+ durational_distance = paper_l()->duration_to_dist (delta_t,k);
+ }
symbol_distance += -cols_[i+1].width_[LEFT];
- ideal_arr_[i] = symbol_distance >? durational_distance;
- hooke_arr_[i] = 1; //2.0;
+ ideal_arr[i] = symbol_distance >? durational_distance;
+ hooke_arr[i] = 1; //2.0;
}
}
Moment context_shortest = context_shortest_arr[i];
if (! shortest_playing_len)
{
- warning (_("Can't find a ruling note at ")
- +scol_l (i)->when().str ());
+ warning (_f ("can't find a ruling note at %s",
+ scol_l (i)->when().str ()));
shortest_playing_len = 1;
}
if (! context_shortest)
{
- warning(_("No minimum in measure at ")
- + scol_l (i)->when().str ());
+ warning (_f ("no minimum in measure at %s",
+ scol_l (i)->when().str ()));
context_shortest = 1;
}
Moment delta_t = scol_l (i+1)->when() - scol_l (i)->when ();
* whitespace at the begin of the bar should be fixed at
(about) one interline.
+
[Ross]:
when spacing gets real tight, a smaller fixed value may be
used, so that there are two discrete amounts of whitespace
* whitespace at the end of the bar is the normal amount of
"hinterfleish" that would have been used, had there been
yet another note in the bar.
+
[Ross]:
some editors argue that the bar line should not take any
space, not to hinder the flow of music spaced around a bar
line.
+
[Ross] and [Wanske] do not suggest this, however. Further,
- it introduces some spacing problems and think that it is ugly
+ it introduces some spacing problems and I think that it is ugly
too.
+
[jcn]
*/
// fixed: probably should set minimum (rod/spring)?
cols_[i-1].width_[RIGHT] += interline_f;
// should adjust dist too?
- ideal_arr_[i-1] = ideal_arr_[i-1] >? interline_f;
+ ideal_arr[i-1] = ideal_arr[i-1] >? (2 * interline_f);
}
/*
+ interline_f / 2;
dist = dist >? minimum;
}
-
- // ugh: never let columns touch... try to set over here...
- // ugh: use j iso i triggers ice in gcc-2.7.2.3
- cols_[i].width_[LEFT] -= nw_f / 4;
- ideal_arr_[i] = dist;
+ ideal_arr[i] = dist;
}
}
- for (int i=0; i < ideal_arr_.size(); i++)
+ /*
+ shorter distances should stretch less.
+
+ (and how bout
+
+ hooke[i] = 2 * max_ideal_space - ideal[i]
+
+ ?)
+ */
+ for (int i=0; i < ideal_arr.size(); i++)
+ hooke_arr[i] = 1/ideal_arr[i];
+
+ for (int i=0; i < ideal_arr.size(); i++)
{
- assert (ideal_arr_[i] >=0 && hooke_arr_[i] >=0);
- connect (i, i+1, ideal_arr_[i], hooke_arr_[i]);
+ assert (ideal_arr[i] >=0 && hooke_arr[i] >=0);
+ connect (i, i+1, ideal_arr[i], hooke_arr[i]);
}
}