Javascript 将固定元素放置在页面上其他两个元素附近而不与其中任何元素相交的算法

Javascript 将固定元素放置在页面上其他两个元素附近而不与其中任何元素相交的算法,javascript,Javascript,我需要将固定元素A放置在页面上元素B附近,但不能与元素C重叠。我使用getBoundingClientRect获取现有元素的大小,我知道新元素A的大小和高度。我手动介绍了一些常见情况,但它不是真正通用的,因为B和C可以在任何地方,任何大小。我需要一个合适的解决方案。基本上,我需要算法放置AABB(轴对齐的边界框)最接近第二个AABB,而不被第三个AABB覆盖。当然,它必须留在页面上。B和C通常接近边缘,这使其复杂化 在用矩形覆盖了几十篇论文之后,我能想到的最好的方法是bruteforce: 函

我需要将固定元素A放置在页面上元素B附近,但不能与元素C重叠。我使用getBoundingClientRect获取现有元素的大小,我知道新元素A的大小和高度。我手动介绍了一些常见情况,但它不是真正通用的,因为B和C可以在任何地方,任何大小。我需要一个合适的解决方案。基本上,我需要算法放置AABB(轴对齐的边界框)最接近第二个AABB,而不被第三个AABB覆盖。当然,它必须留在页面上。B和C通常接近边缘,这使其复杂化

在用矩形覆盖了几十篇论文之后,我能想到的最好的方法是bruteforce:

函数aabb相交(a,b){
//如果A和B相交,则返回true
var ca={
x:a.x+a.width/2,
y:a.y+a.高度/2
},
cb={
x:b.x+b.width/2,
y:b.y+b.height/2
},
dx=Math.abs(ca.x-cb.x)-(a.width+b.width)/2,
dy=数学绝对值(ca.y-cb.y)-(a.高度+b.高度)/2;
返回dx<0&&dy<0;
}
函数aabbRandom(w,h,pagew,pageh){
//返回给定大小的随机AABB,并且必须适合页面
返回{
x:Math.round(Math.random()*(pagew-w)),
y:Math.round(Math.random()*(pageh-h)),
宽度:w,
身高:h
};
}
函数aabbDistance(a,b){
//到分离AABB之间的最小距离
var ca={
x:a.x+a.width/2,
y:a.y+a.高度/2
},
cb={
x:b.x+b.width/2,
y:b.y+b.height/2
},
dx=Math.abs(ca.x-cb.x)-(a.width+b.width)/2,
dy=数学绝对值(ca.y-cb.y)-(a.高度+b.高度)/2;
返回Math.max(dx,dy);
}
函数placeNear(a,b,w,h){
//将给定宽度和高度的图元放置在A附近,但不与B相交
var t1=Date.now(),
c=document.createElement('div'),
ra=a.getBoundingClientRect(),
rb=b.getBoundingClientRect(),
rc,
我
m=1e9,
D
最好的;
对于(i=0;i<1000;i++){
rc=aabbRandom(宽、高、窗内宽、窗内高);
如果(!aabbIntersects(rc,ra)和&!aabbIntersects(rc,rb)){
//找到到目标的最小距离
d=AABB距离(ra,rc);
如果(d=0){
m=d;
最佳=rc;
}
}
}
//console.log(Date.now()-t1);
c、 style.position='fixed';
c、 style.width=w+‘px’;
c、 style.height=h+‘px’;
c、 style.border='1px纯蓝色';
c、 style.boxSize='边框框';
c、 style.left=best.x+'px';
c、 style.top=best.y+'px';
c、 text内容='蓝色';
文件.正文.附件(c);
}
附近(
document.getElementById('red'),
document.getElementById('green'),
60,
50
);
绿色

红色
您能与我们分享您迄今为止尝试过的代码吗?这真的很有帮助。非常感谢。我有几个案件是人工处理的。如果第一个元素是button3,第二个元素是div5,则将其放置在button3右侧,div5上方的“高度”px处。我介绍了一些这样的案例,但这还不够,还可以从中提取一些东西。您已经将“页面”问题简化为实际问题:您需要一个2D框放置算法。所以搜索那个?它必须“在一个页面上”工作这一事实是无关紧要的,找到任何解释甚至提供无重叠二维框放置代码的网站,然后将新知识应用到您选择的编程语言(本例中为Javascript)中。还要注意,尽管中心距比较似乎很聪明,这是一种糟糕的聪明:你的代码使用了20个操作,其中一些是函数调用,而我们可以做的简单边界检查是因为你使用了AABB,
return((b2.x@Mike很好的例子:你保存了一个对一个经过良好测试的函数的调用,找到了交集,并用你的坏版本(.Y?)替换它.当我在解决问题时,我不想问自己,如果一条聪明的直线在寻找盒子交点这样的小事上包含错误,我是在试图解决问题,而不是重新设计基本的构建块。