From 4d7bcd45043201961743e79925c91ba003c048ef Mon Sep 17 00:00:00 2001 From: Alex de Mulder Date: Wed, 14 Jan 2015 11:41:47 +0100 Subject: [PATCH] - Added condition to Repulsion similar to BarnesHut to ensure nodes do not overlap. --- HISTORY.md | 1 + dist/vis.js | 8 +++++++- lib/network/mixins/physics/RepulsionMixin.js | 8 +++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 620585b0..3736f185 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -17,6 +17,7 @@ http://visjs.org - Made the node/edge selected by the popup system the same as selected by the click-to-select system. Thank you @pavlos256! - Improved edit edge control nodes positions, altered style a little. - Fixed issue #564 by resetting state to initial when no callback is performed in the return function. +- Added condition to Repulsion similar to BarnesHut to ensure nodes do not overlap. ### Timeline diff --git a/dist/vis.js b/dist/vis.js index 3b2c716f..f759647e 100644 --- a/dist/vis.js +++ b/dist/vis.js @@ -29990,6 +29990,12 @@ return /******/ (function(modules) { // webpackBootstrap dy = node2.y - node1.y; distance = Math.sqrt(dx * dx + dy * dy); + // same condition as BarnesHut, making sure nodes are never 100% overlapping. + if (distance == 0) { + distance = 0.1*Math.random(); + dx = distance; + } + minimumDistance = (combinedClusterSize == 0) ? nodeDistance : (nodeDistance * (1 + combinedClusterSize * this.constants.clustering.distanceAmplification)); var a = a_base / minimumDistance; if (distance < 2 * minimumDistance) { @@ -29999,13 +30005,13 @@ return /******/ (function(modules) { // webpackBootstrap else { repulsingForce = a * distance + b; // linear approx of 1 / (1 + Math.exp((distance / minimumDistance - 1) * steepness)) } + // amplify the repulsion for clusters. repulsingForce *= (combinedClusterSize == 0) ? 1 : 1 + combinedClusterSize * this.constants.clustering.forceAmplification; repulsingForce = repulsingForce / Math.max(distance,0.01*minimumDistance); fx = dx * repulsingForce; fy = dy * repulsingForce; - node1.fx -= fx; node1.fy -= fy; node2.fx += fx; diff --git a/lib/network/mixins/physics/RepulsionMixin.js b/lib/network/mixins/physics/RepulsionMixin.js index e3b56ac7..4b3ef6ac 100644 --- a/lib/network/mixins/physics/RepulsionMixin.js +++ b/lib/network/mixins/physics/RepulsionMixin.js @@ -31,6 +31,12 @@ exports._calculateNodeForces = function () { dy = node2.y - node1.y; distance = Math.sqrt(dx * dx + dy * dy); + // same condition as BarnesHut, making sure nodes are never 100% overlapping. + if (distance == 0) { + distance = 0.1*Math.random(); + dx = distance; + } + minimumDistance = (combinedClusterSize == 0) ? nodeDistance : (nodeDistance * (1 + combinedClusterSize * this.constants.clustering.distanceAmplification)); var a = a_base / minimumDistance; if (distance < 2 * minimumDistance) { @@ -40,13 +46,13 @@ exports._calculateNodeForces = function () { else { repulsingForce = a * distance + b; // linear approx of 1 / (1 + Math.exp((distance / minimumDistance - 1) * steepness)) } + // amplify the repulsion for clusters. repulsingForce *= (combinedClusterSize == 0) ? 1 : 1 + combinedClusterSize * this.constants.clustering.forceAmplification; repulsingForce = repulsingForce / Math.max(distance,0.01*minimumDistance); fx = dx * repulsingForce; fy = dy * repulsingForce; - node1.fx -= fx; node1.fy -= fy; node2.fx += fx;