Javascript 尝试通过循环迭代创建x个随机矩形,但不重叠

Javascript 尝试通过循环迭代创建x个随机矩形,但不重叠,javascript,arrays,math,Javascript,Arrays,Math,这一个已经被我难住了。这更像是一个数学/逻辑问题,而不是一个特定的JS问题,但我正在处理的是JS,我需要将结果逻辑转换为代码 我试图在画布上创建X个非重叠的矩形和/或任意大小的正方形,以实现如下示例图像: (我想创建的盒子数量可以是10到100个,可以给也可以拿。显然,需要的盒子越多,它们都必须越小) 我一直在尝试不同的想法,但这个问题的逻辑一直在远离我 我不想要的是经典的斐波那契螺线盒图案。我希望随机性能在某种程度上解决这个问题,但我也有一个想法,每次都可以搜索存储行的数组,找到最长的行,然

这一个已经被我难住了。这更像是一个数学/逻辑问题,而不是一个特定的JS问题,但我正在处理的是JS,我需要将结果逻辑转换为代码

我试图在画布上创建X个非重叠的矩形和/或任意大小的正方形,以实现如下示例图像:

(我想创建的盒子数量可以是10到100个,可以给也可以拿。显然,需要的盒子越多,它们都必须越小)

我一直在尝试不同的想法,但这个问题的逻辑一直在远离我

我不想要的是经典的斐波那契螺线盒图案。我希望随机性能在某种程度上解决这个问题,但我也有一个想法,每次都可以搜索存储行的数组,找到最长的行,然后从该行上的一个随机点开始

我正在尝试在随机点将画布切成两半,然后将该线添加到数组中。然后根据第一条线的坐标绘制另一条线,然后存储该线,依此类推。。。我将坐标存储在一组对象中,如下所示:

function storeLine(startX, startY, endX, endY, array) {
        array.push({
                start : {
                         x: startX,
                         y: startY
                        },
                end : {
                         x: endX,
                         y: endY
                        }
                });
}
但我很快就遇到了问题,因为我画的第一条横穿整个x轴的线永远是最长的线,最后我得到了很多薄盒子

在一个完美的世界里,我的最终结果会包含一些变量,比如,盒子总数和最小x/y比率,这样我就可以(不知何故>)选择更多的纵向或横向盒子,这样我就可以调整并不断再生,直到得到我喜欢的结果

不管怎样,我一直在思考如何继续,甚至是我是否走上了正确的道路。如果有人想继续走我现在的路,或者有更好的办法,我将永远欠你的债

注意:在检查我的问题后,我认为斐波那契盒模式可以作为起点,但我仍然需要将较大的初始框分割开来,这样当我想要更多的框的总数时,我就不会一直变得越来越小。。。不管怎样,只是一个随机的想法,如果它给了别人一个想法的火花

附加想法:Voronoi模式也会很神奇,但我的数学技能甚至不知道从哪里开始这是一个很酷的想法

你可以用盒子中的盒子(也像一棵树)来思考它。这些框有自己的坐标和大小。长方体可以位于长方体内部,因此要执行此操作,请选择一个要拆分的尺寸标注(水平或垂直),然后将其拆分为任意多个长方体。然后在每一个盒子里,你可以添加更多的盒子,等等。最后,为了画线,你只需要让盒子有能力自己画(并告诉他们的盒子自己画)

下面是一些实现这一点的JS。你可以很容易地玩你想做多少嵌套。有点棘手并且可能需要一些调整的事情是确定如何将空间分成大致均匀的方框(随机相差一点)。我将空间拆分为
n
框所做的是,首先将可用空间的大小
1/n
,然后随机轻推它一点。如果你只使用
remaining*Math.random()
大多数时候你会得到非常窄的框

//可能会利用这个来获得更好的分割效果
//可能在鼠标点击附近分裂
设splitDimension=(l,n)=>{
设splits=[];
剩余=l;
设x=0;
for(设i=0;i{
盒形图(ctx)
});
}
地址框(n,dim){
让我们分开;
如果(尺寸=“x”){
//宽分
拆分=拆分维度(此.w,n)
//将拆分部分换成新的框
this.box=splits.map([x,w])=>{
返回新框(this.x+x,this.y,w,this.h)
});
}否则{
//高空劈裂
splits=splitDimension(此.h,n);
this.box=splits.map([y,h])=>{
返回新框(this.x,this.y+y,this.w,h);
})
}
}
}
让canvas=document.querySelector(“canvas”);
设ctx=canvas.getContext(“2d”);
//让我们做一些盒子吧!
设bigBox=newbox(0,0,canvas.width,canvas.height);
大盒子。大盒子(2,“y”);
//现在,在长方体上的长方体上添加长方体
bigBox.box.forEach(box=>{
框。添加框(3,“x”);
//还有更多的盒子
box.box.forEach(box=>{
盒子。地址盒(2,“y”);
});
});
//现在画盒子!
大盒绘制(ctx);

来自@g23的答案是这个问题的基础,但我想公布我得出的最终结果,以防有人想要一个完整的工作系统来解决这个难题

最终结果是在画布上创建一个框,用户在其中单击,然后在其周围创建4个框。这4个框然后使用@g23的原始答案将其随机分成更小的框。中间的盒子是解决第一条分割线穿过整个图像的方法,因此它看起来像两个随机分割的盒子,它们只是并排贴在一起。有了这个新系统,就永远不会有一条线横穿画布。我还添加了一个保存按钮来下载结果,并添加了滑块来控制所有设置和尺寸:

工作小提琴

var ImageWidth=960
var ImageHeight=540
var direction1=“x”;
var direction2=“y”;
var vert=真;
var largeverticalbox=parseInt(document.getElementById(“lvb”).value);
var inner=parseInt(document.getElementById(“inner”).value);
var minimest=parseInt(document.getElementById(“minimest”).value);
var totalbox=“”;
var clickBoxWidth=200;
var clickBoxHeight=100;
var线