iterate method
Implementation
bool iterate() {
// Initially assume this layout is stable.
var isStable = true;
// The displacement of each node.
final nodeDisplacement = Map.fromEntries(
graph.adjacencyList.keys.map((node) => MapEntry(node, Vector2.zero())));
// Calculate repulsive forces.
for (final node in graph.adjacencyList.keys) {
// Iterate over every _other_ node in the graph.
for (final otherNode
in graph.adjacencyList.keys.where((other) => other != node)) {
final delta = nodeLayout[node]! - nodeLayout[otherNode]!;
nodeDisplacement[node]!.add(delta.normalized() * _f_r(delta.length));
}
}
// Calculate attractive forces.
for (final edge in graph.edgeList) {
final delta = nodeLayout[edge.left]! - nodeLayout[edge.right]!;
nodeDisplacement[edge.left]!.sub(delta.normalized() * _f_a(delta.length));
nodeDisplacement[edge.right]!
.add(delta.normalized() * _f_a(delta.length));
}
for (final node in graph.adjacencyList.keys) {
nodeLayout.update(node, (position) {
final positionChange = nodeDisplacement[node]!.normalized() *
min(nodeDisplacement[node]!.length, t);
final newPosition = position + positionChange;
clampNodeVector(newPosition);
// If the position of this node changes too much, the layout is unstable.
isStable = isStable && positionChange.length < stableThreshold;
return newPosition;
});
}
t *= tDecay;
return isStable;
}