+ double cur_len = configuration_length (force_);
+ double cur_force = force_;
+ bool compressed = false;
+
+ /* just because we are in compress_line () doesn't mean that the line
+ will actually be compressed (as in, a negative force) because
+ we start out with a stretched line. Here, we check whether we
+ will be compressed or stretched (so we know which spring constant to use) */
+ if (configuration_length (0.0) > line_len_)
+ {
+ cur_force = 0.0;
+ cur_len = configuration_length (0.0);
+ compressed = true;
+ }
+
+ fits_ = true;
+
+ assert (line_len_ <= cur_len);
+
+ vector<Spring> sorted_springs = springs_;
+ sort (sorted_springs.begin (), sorted_springs.end (), greater<Spring> ());
+
+ /* inv_hooke is the total flexibility of currently-active springs */
+ double inv_hooke = 0;
+ vsize i = sorted_springs.size ();
+ for (; i && sorted_springs[i - 1].blocking_force () < cur_force; i--)
+ inv_hooke += compressed
+ ? sorted_springs[i - 1].inverse_compress_strength ()
+ : sorted_springs[i - 1].inverse_stretch_strength ();
+ /* i now indexes the first active spring, so */
+ for (; i < sorted_springs.size (); i++)
+ {
+ Spring sp = sorted_springs[i];
+
+ if (isinf (sp.blocking_force ()))
+ break;
+
+ double block_dist = (cur_force - sp.blocking_force ()) * inv_hooke;
+ if (cur_len - block_dist < line_len_)
+ {
+ cur_force += (line_len_ - cur_len) / inv_hooke;
+ cur_len = line_len_;
+
+ /*
+ Paranoia check.
+ */
+ assert (fabs (configuration_length (cur_force) - cur_len) < 1e-6);
+ return cur_force;
+ }
+
+ cur_len -= block_dist;
+ inv_hooke -= compressed ? sp.inverse_compress_strength () : sp.inverse_stretch_strength ();
+ cur_force = sp.blocking_force ();
+ }
+
+ fits_ = false;
+ return cur_force;