我尝试使用TypeScript和React创建一个简单的项目,以便能够生成一个新的<div>
,它具有随机的宽度和高度(最小值/最大值50/300 px),并随机放置在一个 Package 器中(在本例中为1920 x1080)。
目标是检查新生成的div矩形是否与现有div重叠。
如果没有,创建元素,否则生成新的位置和大小并再次检查,目标是尽可能多地填充 Package 器,因为div的最小/最大大小已经设置,并且没有重叠。
到目前为止,我设法编写了生成随机位置和大小的代码,但我在检查冲突和在没有空闲空间时发送消息方面遇到了麻烦。
const [count,setCount]=useState(0)
const wrapper = document.getElementById('wrapper');
var posX:number,posY:number,divSizeH:number,divSizeW:number;
var willOverlap:boolean=false;
function createRandomRectangle(){
divSizeW = Math.round(((Math.random()*250) + 50));
divSizeH = Math.round(((Math.random()*250) + 50));
if (wrapper!=null) {
const width = wrapper.offsetWidth , height = wrapper.offsetHeight;
posX = Math.round( (Math.random() * ( width - divSizeW )) );
posY = Math.round( (Math.random() * ( height - divSizeH )) );
//checking collision
document.querySelectorAll('.Rectangle').forEach(element=>{
var r2 = element.getBoundingClientRect();
//my attempt //if(((posX>=r2.x&&posX<=r2.right)&&(posY>=r2.top&&posY<=r2.bottom))||((posX+divSizeW>=r2.x&&posX+divSizeW<=r2.right)&&(posY>=r2.top&&posY<=r2.bottom))||((posX>=r2.x&&posX<=r2.right)&&(posY+divSizeH>=r2.top//&&posY+divSizeH<=r2.bottom))||((posX+divSizeW>=r2.x&&posX+divSizeW<=r2.right)&&(posY+divSizeH>=r2.top&&posY+divSizeH<=r2.bottom))){
//copied from someone elses code for checking collisions
if((posX <= r2.x && r2.x <= posX+divSizeW) && (posY <= r2.y && r2.y <= posY+divSizeH) ||
(posX <= r2.x && r2.x <= posX+divSizeW) && (posY <= r2.bottom && r2.bottom <= posY+divSizeH) ||
(posX <= r2.x+r2.height && r2.x+r2.height <= posX+divSizeW) && (posY <= r2.y+r2.width && r2.y+r2.width <= posY+divSizeW) ||
(posX <= r2.x+r2.height && r2.x+r2.height <= posX+divSizeW) && (posY <= r2.y && r2.y <= posY+divSizeW)){
willOverlap=true;
while(willOverlap){
posX = Math.round((Math.random() * ( width- divSizeW)));
posY = Math.round((Math.random() * ( height- divSizeH)));
divSizeW = Math.round(((Math.random()*250) + 50));
divSizeH = Math.round(((Math.random()*250) + 50));
if(!(((posX>=r2.x&&posX<=r2.right)&&(posY>=r2.top&&posY<=r2.bottom))||((posX+divSizeW>=r2.x&&posX+divSizeW<=r2.right)&&(posY>=r2.top&&posY<=r2.bottom))||((posX>=r2.x&&posX<=r2.right)&&(posY+divSizeH>=r2.top&&posY+divSizeH<=r2.bottom))||((posX+divSizeW>=r2.x&&posX+divSizeW<=r2.right)&&(posY+divSizeH>=r2.top&&posY+divSizeH<=r2.bottom)))){
willOverlap=false;
}
}
}
})
}
}
//if there is no more place send message and dont create....
const newDiv = document.createElement('div');
newDiv.classList.add('Rectangle');
newDiv.style.width=divSizeW+"px";
newDiv.style.height=divSizeH+"px";
newDiv.style.left=posX+"px";
newDiv.style.top=posY+"px";
boxxy?.appendChild(newDiv);
setCount(count+1);
}
1条答案
按热度按时间xqkwcwgp1#
正如你开始猜测的那样,你需要重复你的代码(这里是新的位置和大小+检查碰撞),以防你发现碰撞。
但是,由于您在
forEach
循环中对已有的矩形列表执行了重复操作,因此新生成的位置和大小不会与之前的矩形(列表的开头)进行重新检查,因此您可能会遇到冲突元素。另一个问题,更困难的是,检测你的 Package 器什么时候是“满的”,或者更确切地说,当空白的空间不能再容纳任何新的矩形,给定他们的最小尺寸.因为这一步是如此复杂,让我们暂时把它放在一边,并使用一个更简单的方法,通过使用最大数量的重复.
通过这种简化,您的算法可能如下所示: