source file of the GNU LilyPond music typesetter
- (c) 1996,1997 Han-Wen Nienhuys <hanwen@stack.nl>
+ (c) 1996--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
#include <math.h>
#include <limits.h>
+#include "killing-cons.tcc"
#include "spring-spacer.hh"
-#include "p-col.hh"
+#include "paper-column.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"
Vector
-Spring_spacer::default_solution()const
+Spring_spacer::default_solution() const
{
- return try_initial_solution() ;
+ return try_initial_solution();
}
Score_column*
-Spring_spacer::scol_l(int i)
+Spring_spacer::scol_l (int i)
{
- return (Score_column*)cols[i].pcol_l_;
+ return dynamic_cast<Score_column*>(cols_[i].pcol_l_);
}
const Real COLFUDGE=1e-3;
template class P<Real>; // ugh.
bool
-Spring_spacer::contains(PCol const *w)
+Spring_spacer::contains_b (Paper_column const *w)
{
- for (int i=0; i< cols.size(); i++)
- if (cols[i].pcol_l_ == w)
- return true;
- return false;
+ for (int i=0; i< cols_.size(); i++)
+ if (cols_[i].pcol_l_ == w)
+ return true;
+ return false;
}
Spring_spacer::OK() const
{
#ifndef NDEBUG
- for (int i = 1; i < cols.size(); i++)
- assert(cols[i].rank_i_ > cols[i-1].rank_i_);
- for (int i = 1; i < loose_col_arr_.size(); i++)
- assert(loose_col_arr_[i].rank_i_ > loose_col_arr_[i-1].rank_i_);
-#endif
+ for (int i = 1; i < cols_.size(); i++)
+ assert (cols_[i].rank_i_ > cols_[i-1].rank_i_);
+#endif
}
/**
- Make sure no unconnected columns happen.
+ Make sure no unconnected columns happen.
*/
void
-Spring_spacer::handle_loose_cols()
+Spring_spacer::handle_loose_cols()
{
- Union_find connected(cols.size());
- Array<int> fixed;
- for (PCursor<Idealspacing*> i(ideal_p_list_.top()); i.ok(); i++){
- connected.connect(i->left_i_,i->right_i_);
+ Union_find connected (cols_.size());
+ Array<int> fixed;
+
+ for (Cons<Idealspacing> *i = ideal_p_list_; i; i = i->next_)
+ {
+ connected.connect (i->car_->cols_drul_[LEFT],i->car_->cols_drul_[RIGHT]);
}
- for (int i = 0; i < cols.size(); i++)
- if (cols[i].fixed())
- fixed.push(i);
- for (int i=1; i < fixed.size(); i++)
- connected.connect(fixed[i-1], fixed[i]);
-
- for (int i = cols.size(); i--; ) {
- if (! connected.equiv(fixed[0], i)) {
- warning("unconnected column: " + String(i));
- loosen_column(i);
+ for (int i = 0; i < cols_.size(); i++)
+ if (cols_[i].fixed_b())
+ fixed.push (i);
+ for (int i=1; i < fixed.size(); i++)
+ connected.connect (fixed[i-1], fixed[i]);
+
+ /*
+ If columns do not have spacing information set, we need to supply our own.
+ */
+ Real d = paper_l ()->get_var ("loose_column_distance");
+ for (int i = cols_.size(); i--;)
+ {
+ if (! connected.equiv (fixed[0], i))
+ {
+ connected.connect (i-1, i);
+ connect (i-1, i, d, 1.0);
}
}
- OK();
}
-
-/**
- Guess a stupid position for loose columns. Put loose columns at
- regular distances from enclosing calced columns
- */
-void
-Spring_spacer::position_loose_cols(Vector &sol_vec)const
+bool
+Spring_spacer::check_constraints (Vector v) const
{
- if (!loose_col_arr_.size())
- return ;
- assert(sol_vec.dim());
- Array<bool> fix_b_arr;
- fix_b_arr.set_size(cols.size() + loose_col_arr_.size());
- Real utter_right_f=-infinity_f;
- Real utter_left_f =infinity_f;
- for (int i=0; i < loose_col_arr_.size(); i++) {
- fix_b_arr[loose_col_arr_[i].rank_i_] = false;
- }
- for (int i=0; i < cols.size(); i++) {
- int r= cols[i].rank_i_;
- fix_b_arr[r] = true;
- utter_right_f = utter_right_f >? sol_vec(i);
- utter_left_f = utter_left_f <? sol_vec(i);
- }
- Vector v(fix_b_arr.size());
- int j =0;
- int k =0;
- for (int i=0; i < v.dim(); i++) {
- if (fix_b_arr[i]) {
- assert(cols[j].rank_i_ == i);
- v(i) = sol_vec(j++);
- } else {
- Real left_pos_f =
- (j>0) ?sol_vec(j-1) : utter_left_f;
- Real right_pos_f =
- (j < sol_vec.dim()) ? sol_vec(j) : utter_right_f;
- int left_rank = (j>0) ? cols[j-1].rank_i_ : 0;
- 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++];
- int r = loose.rank_i_ ;
- assert(r > left_rank && r < right_rank);
-
- v(i) = (r - left_rank)*left_pos_f/ d_r +
- (right_rank - r) *right_pos_f /d_r;
+ int dim=v.dim();
+ assert (dim == cols_.size());
+ DOUT << "checking " << v;
+ for (int i=0; i < dim; i++)
+ {
+ if (cols_[i].fixed_b() &&
+ abs (cols_[i].fixed_position() - v (i)) > COLFUDGE)
+ {
+ DOUT << "Fixpos broken\n";
+ return false;
+ }
+ Array<Spacer_rod> const &rods (cols_[i].rods_[RIGHT]);
+ for (int j =0; j < rods.size (); j++)
+ {
+ int other =rods[j].other_idx_;
+ 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';
+ return false;
+ }
}
+
}
- sol_vec = v;
+ return true;
}
-
-bool
-Spring_spacer::check_constraints(Vector v) const
-{
- int dim=v.dim();
- assert(dim == cols.size());
-
- for (int i=0; i < dim; i++) {
-
- if (cols[i].fixed()&&
- abs(cols[i].fixed_position() - v(i)) > COLFUDGE)
- return false;
-
- if (!i)
- continue;
-
- Real mindist=cols[i-1].minright()
- +cols[i].minleft();
-
- // ugh... compares
- Real dif =v(i) - v(i-1)- mindist;
- bool b = (dif > - COLFUDGE);
-
-
- if (!b)
- return false;
+/** try to generate a solution which obeys the min
+ distances and fixed positions
+ */
+Vector
+Spring_spacer::try_initial_solution() const
+{
+ Vector v;
+ if (!try_initial_solution_and_tell (v))
+ {
+ warning (_ ("I'm too fat; call Oprah"));
}
- return true;
+ return v;
+
}
bool
-Spring_spacer::check_feasible() const
+Spring_spacer::try_initial_solution_and_tell (Vector &v) const
{
- Vector sol(try_initial_solution());
- return check_constraints(sol);
-}
+ int dim=cols_.size();
+ bool succeeded = true;
+ Vector initsol (dim);
-/// generate a solution which obeys the min distances and fixed positions
-Vector
-Spring_spacer::try_initial_solution() const
-{
- int dim=cols.size();
- Vector initsol(dim);
- for (int i=0; i < dim; i++) {
- if (cols[i].fixed()) {
- initsol(i)=cols[i].fixed_position();
-
- if (i > 0) {
- Real r =initsol(i-1) + cols[i-1].minright();
- if (initsol(i) < r ) {
- warning("overriding fixed position");
- initsol(i) =r;
- }
+ assert (cols_[0].fixed_b ());
+ DOUT << "fixpos 0 " << cols_[0].fixed_position ();
+ for (int i=0; i < dim; i++)
+ {
+ Real min_x = i ? initsol (i-1) : cols_[0].fixed_position ();
+ Array<Spacer_rod> const &sr_arr(cols_[i].rods_[LEFT]);
+ for (int j=0; j < sr_arr.size (); j++)
+ {
+ min_x = min_x >? (initsol (sr_arr[j].other_idx_) + sr_arr[j].distance_f_);
+ }
+ initsol (i) = min_x;
+
+ if (cols_[i].fixed_b())
+ {
+ initsol (i)=cols_[i].fixed_position();
+ if (initsol (i) < min_x )
+ {
+ DOUT << "failing: init, min : " << initsol (i) << " " << min_x << '\n';
+ initsol (i) = min_x;
+ succeeded = false;
}
-
- } else {
- Real mindist=cols[i-1].minright()
- +cols[i].minleft();
- if (mindist < 0.0)
- warning("Excentric column");
- initsol(i)=initsol(i-1)+mindist;
- }
+ }
}
-
- return initsol;
+ v = initsol;
+
+ DOUT << "tried and told solution: " << v;
+ if (!succeeded)
+ DOUT << "(failed)\n";
+ return succeeded;
}
-Vector
-Spring_spacer::find_initial_solution() const
-{
- Vector v(try_initial_solution());
- assert(check_constraints(v));
- return v;
-}
-
// generate the matrices
void
-Spring_spacer::make_matrices(Matrix &quad, Vector &lin, Real &c) const
+Spring_spacer::make_matrices (Matrix &quad, Vector &lin, Real &c) const
{
- quad.fill(0);
- lin.fill(0);
- c = 0;
-
- for (PCursor<Idealspacing*> i(ideal_p_list_.top()); i.ok(); i++) {
- int l = i->left_i_;
- int r = i->right_i_;
+ quad.fill (0);
+ lin.fill (0);
+ c = 0;
+
+ for (Cons<Idealspacing> *p =ideal_p_list_; p; p = p->next_)
+ {
+ Idealspacing *i = p->car_;
+ int l = i->cols_drul_[LEFT];
+ int r = i->cols_drul_[RIGHT];
- quad(r,r) += i->hooke_f_;
- quad(r,l) -= i->hooke_f_;
- quad(l,r) -= i->hooke_f_;
- quad(l,l) += i->hooke_f_;
+ quad (r,r) += i->hooke_f_;
+ quad (r,l) -= i->hooke_f_;
+ quad (l,r) -= i->hooke_f_;
+ quad (l,l) += i->hooke_f_;
- lin(r) -= i->space_f_*i->hooke_f_;
- lin(l) += i->space_f_*i->hooke_f_;
+ lin (r) -= i->space_f_*i->hooke_f_;
+ lin (l) += i->space_f_*i->hooke_f_;
- c += sqr(i->space_f_);
+ c += sqr (i->space_f_);
}
+
+ if (quad.dim() > 10)
+ quad.set_band();
+
+
}
void
-Spring_spacer::set_fixed_cols(Mixed_qp &qp)const
+Spring_spacer::set_fixed_cols (Mixed_qp &qp) const
{
- for (int j=0; j < cols.size(); j++)
- if (cols[j].fixed())
- qp.add_fixed_var(j,cols[j].fixed_position());
-
-
-}
+ for (int j=0; j < cols_.size(); j++)
+ if (cols_[j].fixed_b())
+ qp.add_fixed_var (j,cols_[j].fixed_position());
+}
// put the constraints into the LP problem
void
-Spring_spacer::make_constraints(Mixed_qp& lp) const
-{
- int dim=cols.size();
- for (int j=0; j < dim; j++) {
- Colinfo c=cols[j];
- if (j > 0){
- Vector c1(dim);
-
- c1(j)=1.0 ;
- c1(j-1)=-1.0 ;
- lp.add_inequality_cons(c1, cols[j-1].minright() +
- cols[j].minleft());
+Spring_spacer::make_constraints (Mixed_qp& lp) const
+{
+ int dim=cols_.size();
+
+ for (int j=0; j < dim -1; j++)
+ {
+ Array<Spacer_rod> const&rod_arr (cols_[j].rods_[RIGHT]);
+ for (int i = 0; i < rod_arr.size (); i++)
+ {
+ Vector c1(dim);
+ c1(rod_arr[i].other_idx_)=1.0 ;
+ c1(j)=-1.0 ;
+
+ lp.add_inequality_cons (c1, rod_arr[i].distance_f_);
}
}
}
-void
-Spring_spacer::lower_bound_solution(Col_hpositions*positions)const
-{
- Mixed_qp lp(cols.size());
- make_matrices(lp.quad,lp.lin, lp.const_term);
- set_fixed_cols(lp);
- Vector start(cols.size());
- start.fill(0.0);
- Vector solution_vec(lp.solve(start));
+Real
+Spring_spacer::calculate_energy_f (Vector solution) const
+{
+ Real e = 0.0;
+ for (Cons<Idealspacing>*p =ideal_p_list_; p; p = p->next_)
+ {
+ Idealspacing * i = p->car_;
+ e += i->energy_f(solution(i->cols_drul_[RIGHT]) - solution(i->cols_drul_[LEFT]));
+ }
- positions->energy_f_ = lp.eval(solution_vec);
- positions->config = solution_vec;
- positions->satisfies_constraints_b_ = check_constraints(solution_vec);
+ return e;
}
-
void
-Spring_spacer::solve(Col_hpositions*positions) const
+Spring_spacer::lower_bound_solution (Column_x_positions*positions) const
{
- assert(check_feasible());
-
- Mixed_qp lp(cols.size());
- make_matrices(lp.quad,lp.lin, lp.const_term);
- make_constraints(lp);
- set_fixed_cols(lp);
- Vector start=find_initial_solution();
- Vector solution_vec(lp.solve(start));
-
-
- positions->satisfies_constraints_b_ = check_constraints(solution_vec);
- if (!positions->satisfies_constraints_b_) {
- WARN << "solution doesn't satisfy constraints.\n" ;
- }
- position_loose_cols(solution_vec);
- positions->energy_f_ = lp.eval(solution_vec);
- positions->config = solution_vec;
- positions->error_col_l_arr_ = error_pcol_l_arr();
-
+ Mixed_qp lp (cols_.size());
+ make_matrices (lp.quad_,lp.lin_, lp.const_term_);
+ set_fixed_cols (lp);
+
+ Vector start (cols_.size());
+ start.fill (0.0);
+ Vector solution_vec (lp.solve (start));
+
+ DOUT << "Lower bound sol: " << solution_vec;
+ positions->energy_f_ = calculate_energy_f (solution_vec);
+ positions->config_ = solution_vec;
+ positions->satisfies_constraints_b_ = check_constraints (solution_vec);
}
-/**
- add one column to the problem.
-*/
-void
-Spring_spacer::add_column(PCol *col, bool fixed, Real fixpos)
+Spring_spacer::Spring_spacer ()
{
- Colinfo c(col,(fixed)? &fixpos : 0);
- if (cols.size())
- c.rank_i_ = cols.top().rank_i_+1;
- else
- c.rank_i_ = 0;
- cols.push(c);
+ ideal_p_list_ =0;
+ energy_normalisation_f_ = 1.0;
}
-Line_of_cols
-Spring_spacer::error_pcol_l_arr()const
+void
+Spring_spacer::solve (Column_x_positions*positions) const
{
- Array<PCol*> retval;
- for (int i=0; i< cols.size(); i++)
- if (cols[i].ugh_b_)
- retval.push(cols[i].pcol_l_);
- for (int i=0; i < loose_col_arr_.size(); i++) {
- retval.push(loose_col_arr_[i].pcol_l_);
+ DOUT << "Spring_spacer::solve ()...";
+
+ Vector solution_try;
+
+ bool constraint_satisfaction = try_initial_solution_and_tell (solution_try);
+ if (constraint_satisfaction)
+ {
+ Mixed_qp lp (cols_.size());
+ 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' ;
+ }
+ positions->energy_f_ = calculate_energy_f (solution_vec);
+ positions->config_ = solution_vec;
}
- return retval;
+ else
+ {
+ positions->set_stupid_solution (solution_try);
+ }
+
+ DOUT << "Finished Spring_spacer::solve ()...";
}
+/**
+ add one column to the problem.
+*/
void
-Spring_spacer::loosen_column(int i)
+Spring_spacer::add_column (Paper_column *col, bool fixed, Real fixpos)
{
- Colinfo c=cols.get(i);
- for (PCursor<Idealspacing*> j(ideal_p_list_.top()); j.ok(); j++){
- if (j->left_i_ == i|| j->right_i_ == i)
- j.del();
- else
- j++;
+ Column_info c (col,(fixed)? &fixpos : 0);
+ int this_rank = cols_.size();
+ c.rank_i_ = this_rank;
+
+ for (int i=0; i < col->minimal_dists_arr_drul_[LEFT].size (); i++)
+ {
+ Column_rod &cr = col->minimal_dists_arr_drul_[LEFT][i];
+ int left_idx = cr.other_l_->rank_i () - cols_[0].pcol_l_->rank_i ();
+ if (left_idx < 0)
+ continue;
+
+ if (cols_[left_idx].pcol_l_ != cr.other_l_)
+ continue;
+
+ Spacer_rod l_rod;
+ l_rod.distance_f_ = cr.distance_f_;
+ l_rod.other_idx_ = left_idx;
+ c.rods_[LEFT].push (l_rod);
+
+ Spacer_rod r_rod;
+ r_rod.distance_f_ = cr.distance_f_;
+ r_rod.other_idx_ = this_rank;
+ cols_[left_idx].rods_[RIGHT].push (r_rod);
}
- c.ugh_b_ = true;
-
- int j=0;
- for (; j < loose_col_arr_.size(); j++) {
- if (loose_col_arr_[j].rank_i_ > c.rank_i_)
- break;
+
+ for (int i=0; i < col->spring_arr_drul_[LEFT].size (); i++)
+ {
+ Column_spring &cr = col->spring_arr_drul_[LEFT][i];
+ int idx = cr.other_l_->rank_i () - cols_[0].pcol_l_->rank_i ();
+ if (idx < 0)
+ continue;
+
+ if (cols_[idx].pcol_l_ != cr.other_l_)
+ continue;
+ connect (idx, this_rank, cr.distance_f_, cr.strength_f_);
}
- loose_col_arr_.insert(c,j);
+
+ cols_.push (c);
}
Spring_spacer::print() const
{
#ifndef NPRINT
- for (int i=0; i < cols.size(); i++) {
- mtor << "col " << i<<' ';
- cols[i].print();
+ for (int i=0; i < cols_.size(); i++)
+ {
+ DOUT << "col " << i << " ";
+ cols_[i].print();
}
- for (PCursor<Idealspacing*> i(ideal_p_list_.top()); i.ok(); i++){
- i->print();
+
+ for (Cons<Idealspacing> *p =ideal_p_list_; p; p = p->next_)
+ {
+ p->car_->print();
}
#endif
-
}
void
-Spring_spacer::connect(int i, int j, Real d, Real h)
+Spring_spacer::connect (int i, int j, Real d, Real h)
{
- Idealspacing * s = new Idealspacing;
- s->left_i_ = i;
- s->right_i_ = j;
- s->space_f_ = d;
- s->hooke_f_ = h;
-
- ideal_p_list_.bottom().add(s);
-}
+ assert(d >= 0 && d <= 100 CM);
+ assert(h >=0);
-/**
- walk through all durations in all Score_columns
- */
-struct Durations_iter
-{
- Spring_spacer * sp_l_;
- int col_i_;
- int d_i_;
-
- Durations_iter(Spring_spacer*);
-
- Moment duration()const;
- Moment when()const;
-
- bool ok()const;
- void next();
-};
+ Idealspacing * s = new Idealspacing;
-Durations_iter::Durations_iter(Spring_spacer * s)
-{
- col_i_ =0;
- d_i_ =0; // ugh
-
- sp_l_ = s;
- if (! sp_l_->scol_l(col_i_)->durations.size() )
- next();
-}
-
-Moment
-Durations_iter::duration() const
-{
- return sp_l_->scol_l(col_i_)->durations[d_i_];
-}
-
-bool
-Durations_iter::ok()const{
- return col_i_ < sp_l_->cols.size();
-}
+ s->cols_drul_[LEFT] = i ;
+ s->cols_drul_[RIGHT] = j;
+ s->space_f_ = d;
+ s->hooke_f_ = h;
-Moment
-Durations_iter::when()const{
- return sp_l_->scol_l(col_i_)->when();
+ ideal_p_list_ = new Killing_cons<Idealspacing> (s, ideal_p_list_);
}
void
-Durations_iter::next()
+Spring_spacer::prepare()
{
- d_i_ ++;
- while ( col_i_ < sp_l_->cols.size()
- && d_i_ >= sp_l_->scol_l(col_i_)->durations.size()){
- col_i_ ++;
- d_i_ =0;
- }
+ handle_loose_cols();
+ print();
}
-
-/**
- generate springs between columns.
-
- UNDER DESTRUCTION
-
- TODO: This needs rethinking. Spacing should take optical
- effects into account, and should be local (measure wide)
-
- The algorithm is taken from :
-
- John S. Gourlay. ``Spacing a Line of Music,'' Technical Report
- OSU-CISRC-10/87-TR35, Department of Computer and Information
- Science, The Ohio State University, 1987.
-
- */
-void
-Spring_spacer::calc_idealspacing()
+Line_spacer*
+Spring_spacer::constructor()
{
-
- for (int i=0; i < cols.size(); i++)
- scol_l(i)->preprocess();
-
- /* get the shortest running note at a time. */
- Array<Moment> shortest_arr_;
- {
- Durations_iter d_iter(this);
- for (int i=0; i < cols.size(); i++) {
- Moment now = scol_l(i)->when();
- while ( d_iter.ok() && now >= d_iter.when() ) {
- if ( now < d_iter.when() + d_iter.duration())
- break;
- d_iter.next();
- }
- if ( d_iter.ok() && now >= d_iter.when()) {
- Durations_iter d2 = d_iter;
- Moment shortest = infinity_mom;
- while (d2.ok() && d2.when() <= now) {
- shortest = shortest <? d2.duration();
- d2.next();
- }
- shortest_arr_.push( shortest );
- } else
- shortest_arr_.push(0);
- }
-
- }
-#ifndef NPRINT
- mtor << "shortest:[ ";
- for (int i=0; i < shortest_arr_.size(); i++)
- mtor << shortest_arr_[i] << " ";
- mtor << "]\n";
-#endif
-
- Array<Real> ideal_arr_;
- Array<Real> hooke_arr_;
- for (int i=0; i < cols.size(); i++){
- ideal_arr_.push( -1.0);
- hooke_arr_.push(1.0);
- }
-
- for (int i=0; i < cols.size(); i++) {
- if ( !scol_l(i)->musical_b()) {
- Real symbol_distance =cols[i].minright() + 2 PT;
- Real durational_distance = 0;
-
- if (i+1 < cols.size()) {
- Moment delta_t = scol_l(i+1)->when() - scol_l(i)->when() ;
- if (delta_t)
- durational_distance = paper_l()->duration_to_dist(delta_t) ;
- symbol_distance += cols[i+1].minleft();
- }
-
- ideal_arr_[i] = symbol_distance >? durational_distance;
- hooke_arr_[i] = 2.0;
- }
- }
- for (int i=0; i < cols.size(); i++) {
- if (scol_l(i)->musical_b()) {
- Moment shortest_len = shortest_arr_[i];
- if ( ! shortest_len ) {
- warning( "Can't find a ruling note at "
- +String( scol_l(i)->when()));
- shortest_len = 1;
- }
- Moment delta_t = scol_l(i+1)->when() - scol_l(i)->when();
- Real dist = paper_l()->duration_to_dist(shortest_len);
- dist *= delta_t / shortest_len;
- if (!scol_l(i+1)->musical_b() ) {
-
- Real minimum_dist = cols[i+1].minleft() + 2 PT + cols[i].minright() ;
- if (ideal_arr_[i+1] + minimum_dist < dist) {
- ideal_arr_[i] = dist - ideal_arr_[i+1];
- // hooke_arr_[i+1] =1.0;
- } else {
- ideal_arr_[i] = minimum_dist;
- }
-
- } else
- ideal_arr_[i] = dist;
- }
- }
-
- for (int i=0; i < ideal_arr_.size()-1; i++) {
- assert (ideal_arr_[i] >=0 && hooke_arr_[i] >=0);
- connect(i, i+1, ideal_arr_[i], hooke_arr_[i]);
- }
+ return new Spring_spacer;
}
-void
-Spring_spacer::prepare()
-{
- calc_idealspacing();
- handle_loose_cols();
- print();
-}
-Line_spacer*
-Spring_spacer::constructor()
+Spring_spacer::~Spring_spacer()
{
- return new Spring_spacer;
+ delete ideal_p_list_;
}
-