summaryrefslogtreecommitdiffstats
path: root/src/fdgl.hpp
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/fdgl.hpp
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/fdgl.hpp')
-rw-r--r--src/fdgl.hpp47
1 files changed, 34 insertions, 13 deletions
diff --git a/src/fdgl.hpp b/src/fdgl.hpp
index 42b3538..084ebed 100644
--- a/src/fdgl.hpp
+++ b/src/fdgl.hpp
@@ -16,9 +16,8 @@
#include <float.h>
#include <math.h>
-static const double SPRING_K = 16.0;
-static const double CHARGE_KE = 40000.0;
-static const double AREA_WEIGHT = 0.5;
+static const double SPRING_K = 10.0;
+static const double CHARGE_KE = 50000000.0;
struct Region {
Vector pos;
@@ -52,6 +51,13 @@ vec_mult(const Vector& a, const Vector& b)
return a.x * b.x + a.y * b.y;
}
+/** Magnitude. */
+inline double
+vec_mag(const Vector& vec)
+{
+ return sqrt(vec.x * vec.x + vec.y * vec.y);
+}
+
/** Reciprocal of magnitude. */
inline double
vec_rmag(const Vector& vec)
@@ -64,9 +70,9 @@ inline Vector
spring_force(const Vector& a, const Vector& b, double length, double k)
{
const Vector vec = vec_sub(b, a);
- const double rmag = vec_rmag(vec);
- const double displacement = length - (1.0 / rmag);
- return vec_mult(vec, rmag * k * displacement * 0.5);
+ const double mag = vec_mag(vec);
+ const double displacement = length - mag;
+ return vec_mult(vec, k * displacement * 0.5 / mag);
}
/** Spring force with a directional force to align with flow direction. */
@@ -80,14 +86,29 @@ edge_force(const Vector& dir,
return vec_add(dir, spring_force(hpos, tpos, length, k));
}
-/** Modified Coulomb's law */
+/** Constant tide force, does not vary with distance. */
+inline Vector
+tide_force(const Vector& a, const Vector& b, double power)
+{
+ static const double G = 0.0000000000667;
+ const Vector vec = vec_sub(a, b);
+ const double mag = vec_mag(vec);
+ return vec_mult(vec, G * power / mag);
+}
+
+/**
+ Repelling charge force.
+
+ Many FDGL algorithms use charge according to Coulomb's law, but here we use
+ an inverse cube (not squared) law so influence drops off more rapidly with
+ distance. This, in conjunction with a tide, keeps the layout compact.
+*/
inline Vector
repel_force(const Region& a, const Region& b)
{
- const Vector vec = vec_mult(vec_sub(a.pos, b.pos), 4.0);
- const double rmag = vec_rmag(vec);
- const Vector a_weight = vec_mult(a.area, AREA_WEIGHT);
- const Vector b_weight = vec_mult(b.area, AREA_WEIGHT);
- const Vector force = vec_mult(vec, rmag * rmag * rmag * CHARGE_KE * 0.5);
- return vec_mult(force, vec_mult(a_weight, b_weight));
+ const Vector vec = vec_sub(a.pos, b.pos);
+ const double mag = vec_mag(vec);
+ const Vector force = vec_mult(
+ vec, (CHARGE_KE * 0.5 / (mag * mag * mag * mag * mag)));
+ return vec_mult(force, vec_mult(a.area, b.area));
}