跳至内容

多体作用力

多体(或 *n* 体)作用力在所有 节点 之间相互作用。如果 强度 为正,则可以用来模拟重力(吸引力),如果强度为负,则可以用来模拟静电荷(排斥力)。此实现使用四叉树和 Barnes-Hut 近似 来大幅提升性能;可以使用 theta 参数自定义精度。

与仅影响两个链接节点的 链接力 不同,电荷力是全局性的:每个节点都会影响其他所有节点,即使它们位于断开的子图上。

forceManyBody()

源代码 · 使用默认参数创建新的多体作用力。

js
const manyBody = d3.forceManyBody().strength(-100);

manyBody.strength(strength)

源代码 · 如果指定了 strength,则将强度访问器设置为指定数字或函数,重新评估每个节点的强度访问器,并返回此作用力。正值会导致节点相互吸引,类似于重力,而负值会导致节点相互排斥,类似于静电荷。如果未指定 strength,则返回当前强度访问器,其默认值为

js
function strength() {
  return -30;
}

强度访问器针对模拟中的每个 节点 被调用,传入 node 及其基于零的 index。然后将结果数字存储在内部,这样每个节点的强度仅在初始化作用力或使用新的 strength 调用此方法时重新计算,而不是在每次应用作用力时都重新计算。

manyBody.theta(theta)

源代码 · 如果指定了 theta,则将 Barnes-Hut 近似标准设置为指定的数字,并返回此作用力。如果未指定 theta,则返回当前值,其默认值为 0.9。

为了加速计算,此作用力实现了 Barnes-Hut 近似,该近似在每次应用时需要 O(n log n) 时间,其中 n节点 的数量。对于每次应用,四叉树 都会存储当前节点位置;然后,对于每个节点,都会计算所有其他节点对给定节点的组合力。对于距离较远的节点集群,电荷力可以通过将集群视为单个、更大的节点来近似。theta 参数决定近似精度:如果四叉树单元格的宽度 w 与节点到单元格质心距离 l 之比 w / l 小于 theta,则该单元格中的所有节点将被视为单个节点,而不是分别计算。

manyBody.distanceMin(distance)

源代码 · 如果指定了 distance,则将节点之间考虑此作用力的最小距离设置为指定的数字。如果未指定 distance,则返回当前最小距离,其默认值为 1。最小距离为两个附近节点之间的作用力强度建立了上限,避免不稳定。特别是,如果两个节点完全重合,则避免了无限强力的出现;在这种情况下,作用力的方向是随机的。

manyBody.distanceMax(distance)

源代码 · 如果指定了 distance,则将节点之间考虑此作用力的最大距离设置为指定的数字。如果未指定 distance,则返回当前最大距离,其默认值为无穷大。指定有限的最大距离可以提高性能并生成更加局部的布局。