javascript - 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);
}
推荐阅读
- django - 如何在另一个模板语言中使用 Django 模板语言?
- rust - 如何将 &mut Peekable 更改为 &[u8]?
- c# - 拆分具有文本限定符的多行字符串
- ruby-on-rails - 使用两列的组合上传excel数据?
- tcp - 在使用 FIN 数据包发起终止之后从 TCP 连接接收数据包有多常见?
- reactjs - 如何在 reactjs 的一个组件表中打开模态编辑和 addClient
- php - 如果传递参数,Curl PHP 不会获取数据
- java - 找到4个元素的第i个数字的最小值
- jquery - jQuery中是否有任何等效的函数 myfunction(x, y) ?
- java - Java + Spring Boot + REST 安全问题