]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/spring-spacer.cc
release: 1.1.18
[lilypond.git] / lily / spring-spacer.cc
index db27da7950fc1ab5d5de11d4e7c3f17516dd079f..167940a687264948ff5fa1b88218c8f5663ac338 100644 (file)
@@ -3,7 +3,7 @@
 
   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
@@ -68,7 +68,7 @@ Spring_spacer::handle_loose_cols()
   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())
@@ -80,7 +80,7 @@ Spring_spacer::handle_loose_cols()
     {
       if (! connected.equiv (fixed[0], i))
        {
-         warning (_("unconnected column: ") + String (i));
+         warning (_f ("unconnected column: %d", i));
          loosen_column (i);
        }
     }
@@ -133,7 +133,7 @@ Spring_spacer::position_loose_cols (Vector &sol_vec) const
          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);
 
@@ -165,9 +165,9 @@ Spring_spacer::check_constraints (Vector v) const
          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;
            }
        }
@@ -184,7 +184,7 @@ Spring_spacer::try_initial_solution() const
   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;
 
@@ -214,7 +214,7 @@ Spring_spacer::try_initial_solution_and_tell (Vector &v) const
          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;
            }
@@ -240,8 +240,8 @@ Spring_spacer::make_matrices (Matrix &quad, Vector &lin, Real &c) const
 
   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_;
@@ -253,7 +253,7 @@ Spring_spacer::make_matrices (Matrix &quad, Vector &lin, Real &c) const
 
       c += sqr (i->space_f_);
     }
-  // experimental
+
   if (quad.dim() > 10)
     quad.set_band();
   
@@ -295,13 +295,13 @@ Spring_spacer::calculate_energy_f (Vector solution) const
   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_);
@@ -317,13 +317,18 @@ Spring_spacer::lower_bound_solution (Col_hpositions*positions) const
   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)
     {
@@ -331,13 +336,13 @@ Spring_spacer::solve (Col_hpositions*positions) const
       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);
@@ -348,6 +353,7 @@ Spring_spacer::solve (Col_hpositions*positions) const
     {
       positions->set_stupid_solution (solution_try);
     }
+
   DOUT << "Finished Spring_spacer::solve ()...";
 }
 
@@ -357,7 +363,7 @@ Spring_spacer::solve (Col_hpositions*positions) const
 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;
   
@@ -402,10 +408,10 @@ Spring_spacer::error_pcol_l_arr() const
 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++;
@@ -428,7 +434,7 @@ Spring_spacer::print() const
 #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++)
@@ -447,8 +453,8 @@ Spring_spacer::connect (int i, int j, Real d, Real h)
 
   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;
 
@@ -540,13 +546,18 @@ Spring_spacer::get_ruling_durations(Array<Moment> &shortest_playing_arr,
 
 /*
   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
@@ -562,13 +573,13 @@ Spring_spacer::calc_idealspacing()
   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);
   }
 
   /* 
@@ -580,21 +591,21 @@ Spring_spacer::calc_idealspacing()
        {
          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;
        }
     }
 
@@ -609,14 +620,14 @@ Spring_spacer::calc_idealspacing()
          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 ();
@@ -629,6 +640,7 @@ Spring_spacer::calc_idealspacing()
             
            * 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 
@@ -638,13 +650,16 @@ Spring_spacer::calc_idealspacing()
            * 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 think that it is ugly 
            too.
+           
            [jcn]
          */
 
@@ -656,7 +671,7 @@ Spring_spacer::calc_idealspacing()
              // 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);
            }
 
          /* 
@@ -684,17 +699,25 @@ Spring_spacer::calc_idealspacing()
                + 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]);
     }
 }