希望在更大的矩形中生成一些随机的矩形网格。
这似乎是一个相当简单的问题,但不是在这里寻求建议。
这是not a packing problem,因为内部矩形可以具有任何宽度和高度。
但是矩形的数量并不总是相同。
我已经通过不同种类的循环获得了一些结果,但是没有一个是真正有效的。
例如,使用15个矩形,表示它们的一种可能方法是:
O 10 50 60
+----------+---------------------------------------------+----------+-------+
| | | | |
| | | | |
| | | | |
5 +----------+---------------------------------------------+----------+-------+
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
15+----------+---------------------------------------------+----------+-------+
| | | | |
| | | | |
| | | | |
+----------+---------------------------------------------+----------+-------+
| | | | |
| | | | |
| | ↓ | | |
+----------+---------------------------------------------+----------+-------+
然后,坐标将类似于每个内部正方形的左上角(+)的[x,y]点的数组:
[[0,0],[10,0],[50,0],[60,0],[5,0],[5,10],[5,50], ...]
甚至更好的是[[[x,y,w,h]值的数组(左上角x,左上角y,宽度,高度]
[[0,0,10,5],[10,0,40,5],[50,0,10,5],[60,0,10,5],[5,0,10,10],[5,10,40,10],[5,50,20,10], ...]
但是目标是使函数生成任何数量的内部正方形的坐标:例如,使用
14个矩形,表示它们的一种可能方法是:
+----------+----------------------------------+---------------------+-------+ | | | | | | | | | | | | | | | | | | | | | | | | | +----------+----------------------------------+----------+----------+-------+ | | | | | | | | | | +----------+--------+------------------------------------+----------+-------+ | | | | | | | | | | +-------------------+-----------+------------------------+----------+-------+ | | | | | | | | | | | | +-------------------------------+-----------------------------------+-------+
相关链接:
n个矩形的规则网格,该矩形可能跨越多个单元格,并且希望随机分布单元格边界的坐标。
所以我提出了下面的算法:我不熟悉PHP,所以这里是Java语言的实现。我认为您可以看到它是如何工作的:
function tile(big, n) {
// big: outer rectangle
// n: number of subrectangles to create
// determine number of rows and cols
let l = Math.sqrt(big.height * big.width / n);
let ncol = (big.width / l + 1) | 0;
let nrow = (big.height / l + 1) | 0;
let cells = [];
// create grid of m*m cells
for (let j = 0; j < nrow; j++) {
for (let i = 0; i < ncol; i++) {
cells.push(new Cell(i, j, 1, 1));
}
}
// conflate rectangles until target number is reached
while (cells.length > n) {
let k = (cells.length * Math.random()) | 0;
let c = cells[k];
if (c.col + c.colspan < ncol) {
let cc = cells[k + 1];
c.colspan += cc.colspan;
cells.splice(k + 1, 1);
}
}
// generate increasing lists of random numbers
let xx = [0];
let yy = [0];
for (let i = 0; i < ncol; i++) {
xx.push(xx[xx.length - 1] + 0.5 + Math.random());
}
for (let i = 0; i < nrow; i++) {
yy.push(yy[yy.length - 1] + 0.5 + Math.random());
}
// fit numbers to outer rectangle
for (let i = 0; i < ncol; i++) {
xx[i + 1] = (big.width * xx[i + 1] / xx[ncol]) | 0;
}
for (let i = 0; i < nrow; i++) {
yy[i + 1] = (big.height * yy[i + 1] / yy[nrow]) | 0;
}
// create actual rectangles
let res = [];
for (let cell of cells) {
let x = xx[cell.col];
let w = xx[cell.col + cell.colspan] - x;
let y = yy[cell.row];
let h = yy[cell.row + cell.rowspan] - y;
res.push(new Rect(x, y, w, h));
}
return res;
}
注意:
x | 0
是将浮点数转换为整数的廉价方法。我已经使用它将最终坐标捕捉为整数值,但是您也可以使用PHP中的s
或s * ((x / s) | 0)
将它们捕捉为任何网格大小s * intval(x / s)
。Math.random()
返回0到1之间的随机数。创建轴时,我在结果中加了0.5,这样就不会得到非常狭窄的单元格。如果添加得更少,则坐标将更加不规则;如果添加得更多,则坐标将更均匀地分布。