summaryrefslogtreecommitdiffstats
path: root/src/Canvas.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2013-12-20 04:28:15 +0000
committerDavid Robillard <d@drobilla.net>2013-12-20 04:28:15 +0000
commit10de1f9ec25507b5d67fb89d460aa65815e4fe19 (patch)
tree18ae959a0805060e157908448c6dfa5cf8fa2c70 /src/Canvas.cpp
parent5028bd116503d045591782265981f40c7f5699cd (diff)
downloadganv-10de1f9ec25507b5d67fb89d460aa65815e4fe19.tar.gz
ganv-10de1f9ec25507b5d67fb89d460aa65815e4fe19.tar.bz2
ganv-10de1f9ec25507b5d67fb89d460aa65815e4fe19.zip
FDGL: Use inverse cubic charge law and tide force to prevent graph explosion.
git-svn-id: http://svn.drobilla.net/lad/trunk/ganv@5190 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/Canvas.cpp')
-rw-r--r--src/Canvas.cpp26
1 files changed, 22 insertions, 4 deletions
diff --git a/src/Canvas.cpp b/src/Canvas.cpp
index 20180e3..65f2b16 100644
--- a/src/Canvas.cpp
+++ b/src/Canvas.cpp
@@ -734,7 +734,7 @@ GanvCanvasImpl::layout_iteration()
static const double SPRING_K = 14.0;
// A light directional force to push sources to the top left
- static const double DIR_MAGNITUDE = -300.0;
+ static const double DIR_MAGNITUDE = -600.0;
Vector dir = { 0.0, 0.0 };
switch (_gcanvas->direction) {
case GANV_DIRECTION_RIGHT: dir.x = DIR_MAGNITUDE; break;
@@ -795,6 +795,15 @@ GanvCanvasImpl::layout_iteration()
continue;
}
+ /* Add tide force which pulls all objects as if the layout is happening
+ on a flowing river surface. This prevents disconnected components
+ from being ejected, since at some point the tide force will be
+ greater than distant repelling charges. */
+ const Vector mouth = { -10000.0, -10000.0 };
+ node->impl->force = vec_add(
+ node->impl->force,
+ tide_force(mouth, reg.pos, 4000000000000.0));
+
FOREACH_ITEM(_items, j) {
if (i == j || (!GANV_IS_MODULE(*i) && !GANV_IS_CIRCLE(*i))) {
continue;
@@ -818,8 +827,8 @@ GanvCanvasImpl::layout_iteration()
GanvNode* const node = GANV_NODE(*i);
- static const float dur = 0.15; // Time duration
- static const float damp = 0.7; // Velocity damping (momentum loss)
+ static const float dur = 0.1; // Time duration
+ static const float damp = 0.5; // Velocity damping
const bool has_edges = (node->impl->has_in_edges ||
node->impl->has_out_edges);
@@ -827,10 +836,19 @@ GanvCanvasImpl::layout_iteration()
node->impl->vel.x = 0.0;
node->impl->vel.y = 0.0;
} else {
+ node->impl->vel = vec_mult(node->impl->vel, damp);
node->impl->vel = vec_add(node->impl->vel,
vec_mult(node->impl->force, dur));
- node->impl->vel = vec_mult(node->impl->vel, damp);
+ // Clamp velocity
+ const double vel_mag = vec_mag(node->impl->vel);
+ static const double MAX_VEL = 4000.0;
+ if (vel_mag > MAX_VEL) {
+ node->impl->vel = vec_mult(
+ vec_mult(node->impl->vel, 1.0 / vel_mag),
+ MAX_VEL);
+ }
+
// Update position
const Vector dpos = vec_mult(node->impl->vel, dur);
if (fabs(dpos.x) >= 1.0 || fabs(dpos.y) >= 1.0) {