step method
void
step()
Run one step of the simulation.
Implementation
void step() {
if (_currentIteration >= iterations || _temperature < 0.1) {
return;
}
// Calculate repulsive forces between all pairs of nodes
final forces = List<Offset>.filled(nodes.length, Offset.zero);
for (var i = 0; i < nodes.length; i++) {
for (var j = i + 1; j < nodes.length; j++) {
final delta = nodes[i].position - nodes[j].position;
final distance = delta.distance.clamp(0.1, double.infinity);
final force = _repulsiveForce(distance);
final normalized = delta / distance;
final forceVector = normalized * force;
forces[i] = forces[i] + forceVector;
forces[j] = forces[j] - forceVector;
}
}
// Calculate attractive forces along edges
for (final edge in edges) {
final sourceIndex = nodes.indexWhere((n) => n.id == edge.sourceId);
final targetIndex = nodes.indexWhere((n) => n.id == edge.targetId);
if (sourceIndex == -1 || targetIndex == -1) continue;
final delta = nodes[sourceIndex].position - nodes[targetIndex].position;
final distance = delta.distance.clamp(0.1, double.infinity);
final force = _attractiveForce(distance);
final normalized = delta / distance;
final forceVector = normalized * force;
forces[sourceIndex] = forces[sourceIndex] - forceVector;
forces[targetIndex] = forces[targetIndex] + forceVector;
}
// Apply forces with temperature limiting
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].isFixed) continue;
final force = forces[i];
final magnitude = force.distance;
final limited = magnitude > _temperature ? _temperature : magnitude;
if (magnitude > 0) {
final normalized = force / magnitude;
final displacement = normalized * limited;
var newPosition = nodes[i].position + displacement;
// Keep within bounds
newPosition = Offset(newPosition.dx.clamp(50.0, width - 50), newPosition.dy.clamp(50.0, height - 50));
nodes[i] = nodes[i].copyWith(position: newPosition);
}
}
// Cool down
_temperature *= coolingFactor;
_currentIteration++;
}