]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/simple-spacer.cc
*** empty log message ***
[lilypond.git] / lily / simple-spacer.cc
index 08fd455e15cf69ce899602bd522e1b2474598ec2..a7fd8a7680a141835c51ad8a10167a4e12f19112 100644 (file)
@@ -143,7 +143,28 @@ Simple_spacer::active_blocking_force () const
 Real
 Simple_spacer::active_springs_stiffness () const
 {
-  return range_stiffness (0, springs_.size ());
+  Real  stiff =  range_stiffness (0, springs_.size ());
+  if (isinf (stiff))
+    {
+      /*
+       all springs are inactive. Take the stiffness of the
+       latest spring to block.
+       */
+
+      Real max_block_force = -infinity_f;
+      int max_i = -1;
+      for (int i=0; i < springs_.size (); i++)
+       {
+         if (springs_[i].block_force_ > max_block_force)
+           {
+             max_i = i;
+             max_block_force = springs_[i].block_force_;
+           }
+       }
+
+      stiff = springs_[max_i].hooke_;   
+    }
+  return stiff;
 }
 
 void
@@ -185,7 +206,7 @@ Simple_spacer::my_solve_linelen ()
 
       if (conf < line_len_)
        {
-         force_ += (line_len_  - conf) * active_springs_stiffness ();
+         force_ += (line_len_ - conf) * active_springs_stiffness ();
          break;
        }
       else
@@ -214,15 +235,20 @@ LY_DEFINE(ly_solve_spring_rod_problem, "ly:solve-spring-rod-problem",
          "are connected by @var{count-1} springs, and an arbitrary number of rods "
          "Springs have the format (ideal, hooke) and rods (idx1, idx2, distance) "
          "@var{length} is a number, @var{ragged} a boolean "
-         "Return: a list containing the force (#f for non-satisfied constraints)"
-         "followed by positions of the objects."
+         "Return: a list containing the force (#f for non-satisfied constraints) "
+         "followed by the @var{spring-count}+1 positions of the objects. "
          )
 {
-  SCM_ASSERT_TYPE (scm_ilength (springs) >= 0, springs, SCM_ARG1, __FUNCTION__, "list of springs");
+  int len = scm_ilength (springs);
+  if (len == 0)
+    return scm_list_2 (scm_from_double (0.0), scm_from_double (0.0));
+  
+  SCM_ASSERT_TYPE (len >= 0, springs, SCM_ARG1, __FUNCTION__, "list of springs");
   SCM_ASSERT_TYPE (scm_ilength (rods) >= 0, rods, SCM_ARG2, __FUNCTION__, "list of rods");
   SCM_ASSERT_TYPE (scm_is_number (length) || length == SCM_BOOL_F,
                   length, SCM_ARG3, __FUNCTION__, "number or #f");
 
+
   bool is_ragged   = ragged == SCM_BOOL_T; 
   Simple_spacer spacer; 
   for (SCM s = springs; ly_c_pair_p (s); s = ly_cdr (s))
@@ -236,22 +262,20 @@ LY_DEFINE(ly_solve_spring_rod_problem, "ly:solve-spring-rod-problem",
   for (SCM s = rods; ly_c_pair_p (s); s = ly_cdr (s))
     {
       SCM entry = ly_car (s);
-      int l = scm_to_int (ly_car (s));
-      int r = scm_to_int (ly_cadr (s));
-      entry = ly_cddr (s);
+      int l = scm_to_int (ly_car (entry));
+      int r = scm_to_int (ly_cadr (entry));
+      entry = ly_cddr (entry);
       
-      Real distance = scm_to_double (ly_car (s));
+      Real distance = scm_to_double (ly_car (entry));
       spacer.add_rod (l, r, distance);
     }
 
+  spacer.line_len_ = scm_to_double (length);
+      
   if (is_ragged)
     spacer.my_solve_natural_len ();
   else
-    {
-      spacer.line_len_ = scm_to_double (length);
-      
-      spacer.my_solve_linelen ();
-    }
+    spacer.my_solve_linelen ();
 
   Array<Real> posns;
   posns.push (0.0);
@@ -261,17 +285,20 @@ LY_DEFINE(ly_solve_spring_rod_problem, "ly:solve-spring-rod-problem",
       posns.push (posns.top() + l);
     }
 
-  SCM force_return = scm_from_double (spacer.force_);
+  SCM force_return = SCM_BOOL_F;
   if (is_ragged)
     {
       Real len = posns.top ();
       if (spacer.line_len_ - len  >= 0)
        force_return  = scm_from_double ((spacer.line_len_ - len)
                                         * spacer.active_springs_stiffness ());
-      else
-       force_return = SCM_BOOL_F;
     }
-
+  else if (not isinf (spacer.force_)
+          && spacer.is_active ())
+    {
+      force_return = scm_from_double (spacer.force_);
+    }
+  
   SCM retval= SCM_EOL;
   for (int i = posns.size(); i--;)
     {
@@ -297,7 +324,9 @@ Spring_description::Spring_description ()
 bool
 Spring_description::is_sane () const
 {
-  return (hooke_ > 0) &&  !isinf (ideal_) && !isnan (ideal_);
+  return (hooke_ > 0)
+    && ideal_ > 0
+    && !isinf (ideal_) && !isnan (ideal_);
 }
 
 Real