Ваша сила столкновения слишком велика.Сделайте это немного меньше.
lx *= 0.3;
ly *= 0.3;
Центральный прямоугольник может быть добавлен с помощью
nodes.push( { x:500, y:500, width:300, height:300, fx:500, fy:500, center: true });
Рисование ректов теперь должно быть отфильтровано
var g = svg.selectAll("g")
.data(nodes.filter(d => !d.center))
.enter()
.append("g")
И еслиВы также рисуете прямоугольник в центре, вы должны добавить класс
g.append("rect")
.attr("opacity", 0.5)
.attr("class", "node")
.attr("fill", "#ccc" )
.attr("width", d => d.width )
.attr("height", d => d.height )
.attr("rx", 10)
.attr("ry", 10);
И в тик-функции фильтра на ритах с классом
svg.selectAll("rect.node")
.attr("x", d => d.x - d.width / 2 )
.attr("y", d => d.y - d.height / 2 );
Добавить тест, чтобы игнорировать центр rect
if (a.center) return;
Обновлен код силы
nodes.forEach(function (a, i) {
if (a.center) return; // ignore this node
// Apply gravity forces.
a.x += (a.gravity.x - a.x) * kg;
a.y += (a.gravity.y - a.y) * kg;
nodes.slice(i + 1).forEach(function (b) {
dx = (a.x - b.x)
dy = (a.y - b.y)
adx = Math.abs(dx)
ady = Math.abs(dy)
mdx = (1 + spaceAround) * (a.width + b.width) / 2
mdy = (1 + spaceAround) * (a.height + b.height) / 2
if (adx < mdx && ady < mdy) {
l = Math.sqrt(dx * dx + dy * dy)
lx = (adx - mdx) / l * k
ly = (ady - mdy) / l * k
lx *= 0.3;
ly *= 0.3;
// choose the direction with less overlap
if (lx > ly && ly > 0) lx = 0;
else if (ly > lx && lx > 0) ly = 0;
dx *= lx
dy *= ly
a.x -= dx
a.y -= dy
b.x += dx
b.y += dy
}
});
});
Редактировать
Модификация будет делать движение независимым от расстояния прямоугольникацентры.Перемещайте только определенную величину в направлении, противоположном другому центру.
Текущий метод изменяет узлы, находящиеся позже в списке, уже на новую позицию и основывает столкновение следующих узлов на этих новых позициях.Лучше сначала рассчитать движение на основе всех узлов за время N и в конце применить это движение.Это делается в симуляции силы путем вычисления / изменения скорости (d.vx
, d.vy
) узла.Симуляция применит скорость на тике.