Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/254.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在矩形中填充矩形,生成网格坐标_Php_Algorithm_Rectangles_Packing - Fatal编程技术网

Php 在矩形中填充矩形,生成网格坐标

Php 在矩形中填充矩形,生成网格坐标,php,algorithm,rectangles,packing,Php,Algorithm,Rectangles,Packing,希望在更大的矩形中生成一些随机的矩形网格 这看起来是一个相当容易的问题,但它不是,在这里寻求建议 这是因为内部矩形可以有任何宽度和高度 但矩形的数量并不总是相同的 我已经有了一些关于不同类型循环的结果,但是没有一个是真正有效的 例如,对于15个矩形,表示它们的一种可能方式是: O 10 50 60 +----------+------------------------

希望在更大的矩形中生成一些随机的矩形网格

这看起来是一个相当容易的问题,但它不是,在这里寻求建议

这是因为内部矩形可以有任何宽度和高度

但矩形的数量并不总是相同的

我已经有了一些关于不同类型循环的结果,但是没有一个是真正有效的

例如,对于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,0],[50,0],[60,0],[5,0],[5,10],[5,50], ...]
例如,对于14个矩形,表示它们的一种可能方法是:

  +----------+----------------------------------+---------------------+-------+
  |          |                                  |                     |       |
  |          |                                  |                     |       |
  |          |                                  |                     |       |
  |          |                                  |                     |       |
  |          |                                  |                     |       |
  +----------+----------------------------------+----------+----------+-------+
  |          |                                             |          |       |
  |          |                                             |          |       |
  +----------+--------+------------------------------------+----------+-------+
  |                   |                                    |          |       |
  |                   |                                    |          |       |
  +-------------------+-----------+------------------------+----------+-------+
  |                               |                                           |
  |                               |                                           |
  |                               |                                           |
  |                               |                                           |
  +-------------------------------+-----------------------------------+-------+
相关链接:


您的问题有两个方面:您希望创建一个包含n个矩形的规则网格,这些矩形可能跨越多个单元格,并且您希望随机分布单元格边界的坐标

因此,我提出了愚弄算法:

  • 确定网格中的行数和列数,使每个单元格或多或少呈正方形
  • 创建一个由1×1个单元组成的矩形网格。单元数将大于n
  • 合并两个相邻的单元格,直到有n个单元格
  • 现在为单元边界创建随机轴。如果有m列,请创建一个递增值数组,以便第一个坐标为0,最后一个坐标为原始角度的宽度。您可以通过创建一个不断增加的随机数列表,然后使用总宽度进行规范化来实现这一点
  • 最后,使用单元信息(位置、单元跨度)和随机轴创建实际矩形
该算法使用两种矩形表示:首先,它创建“单元格”,其中包含有关行和列索引以及跨距的信息。实际输出是带有左、上、宽和高信息的矩形

我不熟悉PHP,所以这里有一个Javascript实现。我想你可以看到它是如何工作的:

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;
}
功能磁贴(大,n){
//大:外矩形
//n:要创建的子矩形数
//确定行数和列数
设l=Math.sqrt(big.height*big.width/n);
设ncol=(big.width/l+1)| 0;
设nrow=(大高度/l+1)| 0;
let cells=[];
//创建m*m单元格的网格
对于(设j=0;jn){
设k=(cells.length*Math.random())| 0;
设c=单元[k];
if(c.col+c.colspan
注:

  • 上面的代码仅在水平方向上合并单元格。您可以将其更改为垂直合并单元格或两者合并,但由于目前的算法,如果不进行重大修改,您将无法创建宽度和高度超过一个单元格的单元格
  • x | 0
    是一种将浮点数转换为整数的廉价方法。我使用它将最终坐标捕捉为整数值,但您也可以使用PHP中的
    s*((x/s)| 0)或
    s*intval(x/s)
    将它们捕捉为任意网格大小的
    s
代码不太关心美学。它会随机选择单元大小和要合并的单元,这样您可能会得到交叉关节,这看起来不太好。不过,您可以稍微影响结果的规律性:

  • 确定列数和行数时,必须向结果中添加一个,以便在每种情况下使单元格合并。(即使有一个正方形并将一个正方形数字传递为n,也会得到连接的矩形。)如果添加更多,则会得到更多连接的矩形,结果看起来更不规则
  • Math.random()
    返回一个介于0和1之间的随机数。在创建轴时,我在结果中添加了0.5,这样就不会得到非常窄的单元格。如果添加的较少,坐标将更加不规则;如果添加的较多,坐标的分布将更加均匀
  • 也许您可以通过使行坐标均匀而束坐标不规则来获得良好效果

你在评论中提到了漂亮的房子。当您创建网格并放置带有约束的矩形时,可能更容易创建美观的结构,而不是先创建网格,然后再删除关节。

因此,唯一的约束是有n个矩形,并且它们以给定的宽度和高度完全平铺外矩形?绝对是这样。具有