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);
}
我有一个一维数据集(只有水平位置(+圆半径)的元素列表)。
我想实现一个简单的布局算法,以按比例将此数据集显示为圆圈。 问题是碰撞。
我想实现一个“简单”的排斥力来避免碰撞。我不介意圆圈不再有精确的位置。 我正在寻找的结果很简单:
我没有使用 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);
}