summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Neeman <joeneeman@gmail.com>2009-07-24 13:36:36 -0700
committerJoe Neeman <joeneeman@gmail.com>2009-07-24 13:36:36 -0700
commitb76907a5a0c3663895350205e29c7462db4b2b45 (patch)
tree656019f75130c59f0311ca89de50d48889e36796
parentcd3c5c74144d131e3592d15cfd92453c0293ae6b (diff)
Change the treatment of min-distance in springs.
Previously, we ensured that the ideal distance was at least as large as the minimum distance, but it sometimes useful not to. Now, if a spring has minimum distance larger than ideal distance, it will remain fixed (at minimum-distance) for a while as you start to stretch it, but it will stretch eventually. This helps give us a more uniform vertical spacing.
-rw-r--r--lily/include/spring.hh1
-rw-r--r--lily/simple-spacer.cc6
-rw-r--r--lily/spring.cc26
3 files changed, 23 insertions, 10 deletions
diff --git a/lily/include/spring.hh b/lily/include/spring.hh
index c379889adb..4288af5884 100644
--- a/lily/include/spring.hh
+++ b/lily/include/spring.hh
@@ -39,6 +39,7 @@ public:
void set_distance (Real);
void set_min_distance (Real);
+ void ensure_min_distance (Real);
void set_inverse_stretch_strength (Real);
void set_inverse_compress_strength (Real);
void set_blocking_force (Real);
diff --git a/lily/simple-spacer.cc b/lily/simple-spacer.cc
index 1d38d9a70f..bab2a05dcb 100644
--- a/lily/simple-spacer.cc
+++ b/lily/simple-spacer.cc
@@ -216,7 +216,9 @@ Simple_spacer::compress_line ()
{
Spring sp = sorted_springs[i];
- assert (sp.blocking_force () <= cur_force);
+ if (sp.blocking_force () > cur_force)
+ continue;
+
if (isinf (sp.blocking_force ()))
break;
@@ -234,7 +236,7 @@ Simple_spacer::compress_line ()
}
cur_len -= block_dist;
- inv_hooke -= sp.inverse_compress_strength ();
+ inv_hooke -= compressed ? sp.inverse_compress_strength () : sp.inverse_stretch_strength ();
cur_force = sp.blocking_force ();
}
diff --git a/lily/spring.cc b/lily/spring.cc
index 67d41c9c39..fd8e0147cb 100644
--- a/lily/spring.cc
+++ b/lily/spring.cc
@@ -32,10 +32,16 @@ Spring::Spring (Real dist, Real min_dist)
void
Spring::update_blocking_force ()
{
- if (distance_ == min_distance_)
- blocking_force_ = 0.0;
+ if (min_distance_ > distance_)
+ blocking_force_ = (min_distance_ - distance_) / inverse_stretch_strength_;
else
blocking_force_ = (min_distance_ - distance_) / inverse_compress_strength_;
+
+ if (isnan (blocking_force_) || blocking_force_ == infinity_f)
+ blocking_force_ = 0;
+
+ if (blocking_force_ >= 0)
+ inverse_compress_strength_ = 0;
}
/* scale a spring, but in a way that doesn't violate min_distance */
@@ -43,7 +49,7 @@ void
Spring::operator*= (Real r)
{
distance_ = max (min_distance_, distance_ * r);
- inverse_compress_strength_ = distance_ - min_distance_;
+ inverse_compress_strength_ = max (0.0, distance_ - min_distance_);
inverse_stretch_strength_ *= 0.8;
}
@@ -90,7 +96,6 @@ Spring::set_distance (Real d)
programming_error ("insane spring distance requested, ignoring it");
else
{
- min_distance_ = min (min_distance_, d);
distance_ = d;
update_blocking_force ();
}
@@ -104,12 +109,17 @@ Spring::set_min_distance (Real d)
else
{
min_distance_ = d;
- distance_ = max (distance_, min_distance_);
update_blocking_force ();
}
}
void
+Spring::ensure_min_distance (Real d)
+{
+ set_min_distance (max (d, min_distance_));
+}
+
+void
Spring::set_inverse_stretch_strength (Real f)
{
if (isinf (f) || isnan (f) || f < 0)
@@ -147,8 +157,8 @@ Spring::set_blocking_force (Real f)
void
Spring::set_default_strength ()
{
- inverse_compress_strength_ = distance_ - min_distance_;
- inverse_stretch_strength_ = distance_ - min_distance_;
+ inverse_compress_strength_ = (distance_ >= min_distance_) ? distance_ - min_distance_ : 0;
+ inverse_stretch_strength_ = distance_;
}
Real
@@ -163,5 +173,5 @@ Spring::length (Real f) const
force = 0.0;
}
- return distance_ + force * inv_k;
+ return max (min_distance_, distance_ + force * inv_k);
}