Neighbor stop on little velocity changes
This commit is contained in:
@@ -166,7 +166,7 @@ function processData(data, error) {
|
||||
.nodes(nodes)
|
||||
.on("tick", ticked)
|
||||
.on("end", ended);
|
||||
|
||||
};
|
||||
|
||||
function ticked() {
|
||||
// If rendering is selected, then draw at every iteration.
|
||||
@@ -209,8 +209,6 @@ function processData(data, error) {
|
||||
p2 = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function brushEnded() {
|
||||
var s = d3.event.selection,
|
||||
@@ -281,7 +279,10 @@ function startNeighbourSamplingSimulation() {
|
||||
// between nodes.
|
||||
.distance(function (s, t) {
|
||||
return distanceFunction(s, t, props, norm) * MULTIPLIER;
|
||||
}));
|
||||
})
|
||||
.stableVelocity(1.2 * MULTIPLIER)
|
||||
.stableVeloHandler( function(){simulation.stop(); ended();} )
|
||||
);
|
||||
// Restart the simulation.
|
||||
console.log(simulation.force(forceName).neighbourSize(), simulation.force(forceName).sampleSize());
|
||||
simulation.alpha(1).restart();
|
||||
@@ -310,7 +311,7 @@ function startHybridSimulation() {
|
||||
pivots: PIVOTS,
|
||||
numPivots: NUM_PIVOTS
|
||||
};
|
||||
.sampleSize(SAMPLE_SIZE);
|
||||
console.log(configuration);
|
||||
hybridSimulation = d3.hybridSimulation(nodes, configuration);
|
||||
|
||||
let sample = hybridSimulation.sample();
|
||||
|
||||
@@ -34,13 +34,16 @@ export default function (nodes, config) {
|
||||
})
|
||||
.on("end", ended);
|
||||
|
||||
sampleSimulation.force("forces", neighbourSamplingDistance()
|
||||
sampleSimulation
|
||||
.force("forces", neighbourSamplingDistance()
|
||||
.neighbourSize(neighbourSize)
|
||||
.sampleSize(sampleSize)
|
||||
.distanceRange(distanceRange)
|
||||
.distance(distanceFn)
|
||||
);
|
||||
sampleSimulation.alpha(1).restart();
|
||||
.stableVelocity(60)
|
||||
.stableVeloHandler(function(){sampleSimulation.stop(); ended();})
|
||||
)
|
||||
.alpha(1).restart();
|
||||
|
||||
function ended() {
|
||||
event.call("startFull");
|
||||
|
||||
@@ -29,7 +29,9 @@ export default function () {
|
||||
//freeness = 0.85,
|
||||
//springForce = 0.7,
|
||||
//dampingFactor = 0.3,
|
||||
velocity;
|
||||
velocity,
|
||||
stableVelocity = 0,
|
||||
stableVeloHandler = null;
|
||||
|
||||
/**
|
||||
* Calculates the forces at each iteration between the node and the
|
||||
@@ -39,21 +41,28 @@ export default function () {
|
||||
*/
|
||||
function force(alpha) {
|
||||
velocity = 0;
|
||||
for (var i = 0, n = nodes.length; i < n; ++i) {
|
||||
for (let i = 0, n = nodes.length; i < n; ++i) {
|
||||
// Randomize the samples for every node.
|
||||
samples[i] = randomizeSample(i);
|
||||
// Calculate the forces between node and its neighbours.
|
||||
for (var [keyN, valueN] of neighbours[i]) {
|
||||
for (let [keyN, valueN] of neighbours[i]) {
|
||||
setVelocity(i, keyN, valueN, alpha);
|
||||
}
|
||||
// Calculate the forces between node and its sample set.
|
||||
for (var [keyS, valueS] of samples[i]) {
|
||||
for (let [keyS, valueS] of samples[i]) {
|
||||
setVelocity(i, keyS, valueS, alpha);
|
||||
}
|
||||
// Check if there are a better neighbours in a sample array
|
||||
// for each node.
|
||||
findNewNeighbours(i);
|
||||
}
|
||||
velocity /= nodes.length*alpha;
|
||||
// Now total velocity change per node, alpha not considered
|
||||
if(Math.abs(velocity)<stableVelocity && stableVeloHandler!== null){
|
||||
console.log("Neighbour sampling is now", velocity, ", calling stableVeloHandler().")
|
||||
stableVeloHandler();
|
||||
}
|
||||
//else console.log(velocity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +74,7 @@ export default function () {
|
||||
* @param {number} alpha - controls the speed of simulation.
|
||||
*/
|
||||
function setVelocity(sourceId, targetId, dist, alpha) {
|
||||
var source, target, x, y, l;
|
||||
let source, target, x, y, l;
|
||||
source = nodes[sourceId], target = nodes[targetId];
|
||||
// If x or y coordinates not defined, add some randomness.
|
||||
x = target.x + target.vx - source.x - source.vx || jiggle();
|
||||
@@ -73,12 +82,12 @@ export default function () {
|
||||
l = Math.sqrt(x * x + y * y);
|
||||
l = (l - dist) / l * alpha;
|
||||
x *= l, y *= l;
|
||||
velocity += x + y;
|
||||
velocity += Math.abs(x) + Math.abs(y);
|
||||
// Set the calculated velocites for both nodes.
|
||||
target.vx -= x;
|
||||
target.vy -= y;
|
||||
source.vx += x;
|
||||
source.vy += y;
|
||||
target.vx -= x*0.5;
|
||||
target.vy -= y*0.5;
|
||||
source.vx += x*0.5;
|
||||
source.vy += y*0.5;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,11 +98,11 @@ export default function () {
|
||||
|
||||
// Initialize for each node a neighbour and sample arrays
|
||||
// with random values.
|
||||
for (var i = 0, n = nodes.length; i < n; ++i) {
|
||||
var exclude = []; // Array that keeps the indices of nodes to ignore.
|
||||
for (let i = 0, n = nodes.length; i < n; ++i) {
|
||||
let exclude = []; // Array that keeps the indices of nodes to ignore.
|
||||
exclude.push(i);
|
||||
|
||||
var neighbs = createRandomNeighbours(i, exclude, n, neighbourSize);
|
||||
let neighbs = createRandomNeighbours(i, exclude, n, neighbourSize);
|
||||
// Sort the neighbour set by the distances.
|
||||
neighbs = new Map([...neighbs.entries()].sort(sortDistances));
|
||||
neighbours[i] = neighbs;
|
||||
@@ -127,17 +136,17 @@ export default function () {
|
||||
* data set.
|
||||
*/
|
||||
function createRandomNeighbours(index, exclude, max, size) {
|
||||
var randElements = new Map();
|
||||
var triedElements = 0;
|
||||
let randElements = new Map();
|
||||
let triedElements = 0;
|
||||
|
||||
while ((randElements.size < size) && (randElements.size + exclude.length + triedElements < nodes.length)) {
|
||||
var rand = Math.floor((Math.random() * max));
|
||||
let rand = Math.floor((Math.random() * max));
|
||||
// If the rand is already in random list or in exclude list
|
||||
// ignore it and get a new value.
|
||||
while (randElements.has(rand) || exclude.includes(rand)) {
|
||||
rand = Math.floor((Math.random() * max));
|
||||
}
|
||||
var dist = +distance(nodes[index], nodes[rand]);
|
||||
let dist = +distance(nodes[index], nodes[rand]);
|
||||
if (dist <= distanceRange) {
|
||||
randElements.set(rand, dist);
|
||||
} else {
|
||||
@@ -150,14 +159,14 @@ export default function () {
|
||||
|
||||
|
||||
function createRandomSample(index, exclude, max, size) {
|
||||
var randElements = new Map();
|
||||
let randElements = new Map();
|
||||
|
||||
for (var i = 0; i < size; ++i) {
|
||||
for (let i = 0; i < size; ++i) {
|
||||
// Stop when no new elements can be found.
|
||||
if (randElements.size + exclude.length >= nodes.length) {
|
||||
break;
|
||||
}
|
||||
var rand = Math.floor((Math.random() * max));
|
||||
let rand = Math.floor((Math.random() * max));
|
||||
// If the rand is already in random list or in exclude list
|
||||
// ignore it and get a new value.
|
||||
while (randElements.has(rand) || exclude.includes(rand)) {
|
||||
@@ -176,7 +185,7 @@ export default function () {
|
||||
*/
|
||||
function randomizeSample(index) {
|
||||
// Ignore the current neighbours of the node and itself.
|
||||
var exclude = [index];
|
||||
let exclude = [index];
|
||||
exclude = exclude.concat(Array.from(neighbours[index].keys()));
|
||||
return createRandomSample(index, exclude, nodes.length, sampleSize);
|
||||
}
|
||||
@@ -188,11 +197,11 @@ export default function () {
|
||||
* @param {number} index - index of current node.
|
||||
*/
|
||||
function findNewNeighbours(index) {
|
||||
var sample = samples[index];
|
||||
let sample = samples[index];
|
||||
|
||||
if (neighbours[index].size > 0) {
|
||||
for (var [key, value] of sample) {
|
||||
var neighbMax = neighbours[index].entries().next().value;
|
||||
for (let [key, value] of sample) {
|
||||
let neighbMax = neighbours[index].entries().next().value;
|
||||
|
||||
// Check if a value from sample could be a better neighbour
|
||||
// if so, replace it.
|
||||
@@ -212,9 +221,9 @@ export default function () {
|
||||
* @return {number} - stress of the layout.
|
||||
*/
|
||||
function getStress() {
|
||||
var totalDiffSq = 0, totalHighDistSq = 0;
|
||||
for (var i = 0, source, target, realDist, highDist; i < nodes.length; i++) {
|
||||
for (var j = 0; j < nodes.length; j++) {
|
||||
let totalDiffSq = 0, totalHighDistSq = 0;
|
||||
for (let i = 0, source, target, realDist, highDist; i < nodes.length; i++) {
|
||||
for (let j = 0; j < nodes.length; j++) {
|
||||
if (i !== j) {
|
||||
source = nodes[i], target = nodes[j];
|
||||
realDist = Math.hypot(target.x - source.x, target.y - source.y);
|
||||
@@ -238,8 +247,8 @@ export default function () {
|
||||
|
||||
|
||||
function getDistributionData() {
|
||||
var d = [];
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
let d = [];
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
d.push({ "index": i, "size": neighbours[i].size });
|
||||
}
|
||||
return { "maxSize": neighbourSize, "l": nodes.length, "distribution": d };
|
||||
@@ -292,5 +301,12 @@ export default function () {
|
||||
return getDistributionData();
|
||||
};
|
||||
|
||||
force.stableVeloHandler = function (_) {
|
||||
return arguments.length ? (stableVeloHandler = _, force) : stableVeloHandler;
|
||||
};
|
||||
|
||||
force.stableVelocity = function (_) {
|
||||
return arguments.length ? (stableVelocity = _, force) : stableVelocity;
|
||||
};
|
||||
return force;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user