js中的相互斥力

Mutual repulsion force in js

我有一个一维数据集(只有水平位置(+圆半径)的元素列表)。

我想实现一个简单的布局算法,以按比例将此数据集显示为圆圈。 问题是碰撞。

我想实现一个“简单”的排斥力来避免碰撞。我不介意圆圈不再有精确的位置。 我正在寻找的结果很简单:

我没有使用 D3,它是纯 js(和 svg.js),从哪里开始寻找有关此布局的理论信息?提到这股力量的通用名称是什么?有没有类似的例子?

我添加了 min_gap 元素之间的最小边距。所以解决办法是每次移动两个相交距离最远的相交元素一小步。

const elements = [{pos:10, radius:5}, {pos:15, radius: 20}, {pos:20, radius:10}, {pos:150, radius:5}];

const field_size = [0, 300];

const min_gap = 5;
const step = 1;

moveIntersected(elements);

console.log(elements);

function detectCollisions(arr=[]){
    const result = [];
    for(let i=0; i < arr.length - 1; i++){
        let dist = (arr[i+1].pos - arr[i+1].radius) - (arr[i].pos + arr[i].radius);
        if(dist < min_gap){
            result.push([i + 0.5, dist]);
        }
    }
    return result;
}

function moveIntersected(arr=[]){

    const collisions = detectCollisions(arr);
    if(collisions.length < 1) return;
    
    const most_intersected = collisions.sort((a,b) => a[1] - b[1])[0];
    const left = arr[Math.floor(most_intersected[0])];
    const right = arr[Math.ceil(most_intersected[0])];
    
    if(left.pos - left.radius - step >= field_size[0]){
        left.pos -= step;
    } else {
        right.pos += step*2;
    }
    
    if(right.pos + right.radius + step <= field_size[1]){
        right.pos += step;
    } else {
        left.pos -= step*2;
    }
    moveIntersected(arr);
}