You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将矩形划分为N个近正方形单元格的尺寸及偏移计算算法

画布近1:1比例单元格分割算法

核心分割规则

分割目标是尽可能让所有单元格宽高比接近1:1,拆分逻辑固定为:

  • 对任意待拆分矩形,若高度大于宽度,沿垂直(高度)方向对半拆分,得到的两个子块宽度与原块一致,高度为原块的1/2
  • 若宽度大于等于高度,沿水平(宽度)方向对半拆分,得到的两个子块高度与原块一致,宽度为原块的1/2
  • 重复拆分操作,直到得到的单元格总数等于目标数量

符合规则的分割效果参考:
正确分割示例
不符合规则的反例参考:
错误分割示例

计算逻辑

用队列实现广度优先拆分即可,步骤如下:

  1. 初始化队列,队列中初始只有1个矩形块,对应整个画布范围,参数为 xOffset=0, yOffset=0, width=画布总宽度, height=画布总高度
  2. 当队列内块总数小于目标单元格数时,取出队首的块,按照上述规则拆分为2个子块,计算好两个子块的偏移量和尺寸后放回队列
  3. 当队列内块总数等于目标单元格数时,队列中所有块的参数就是最终绘制需要的宽高和偏移量

给定参数计算示例

已知参数:目标单元格数=6,画布高度=600,画布宽度=400,拆分过程如下:

  1. 初始队列共1个块:尺寸400*600,高比宽大,垂直拆分
  2. 拆分后队列共2个块:均为400*300,偏移分别为(0,0)、(0,300),块数不足6,继续拆分
  3. 取出队首400300块,宽比高大,水平拆分为2个200300块,偏移(0,0)、(200,0),队列总块数变为3
  4. 取出队首400300块(偏移0,300),宽比高大,水平拆分为2个200300块,偏移(0,300)、(200,300),队列总块数变为4
  5. 取出队首200300块(偏移0,0),高比宽大,垂直拆分为2个200150块,偏移(0,0)、(0,150),队列总块数变为5
  6. 取出队首200300块(偏移200,0),高比宽大,垂直拆分为2个200150块,偏移(200,0)、(200,150),队列总块数变为6,拆分结束

最终6个单元格的绘制参数:

xOffsetyOffsetwidthheight
0300200300
200300200300
00200150
0150200150
2000200150
200150200150

可直接复用的代码实现(JavaScript)

function generateCells(cellCount, canvasWidth, canvasHeight) {
  // 初始队列放入整个画布块
  const cells = [{
    xOffset: 0,
    yOffset: 0,
    width: canvasWidth,
    height: canvasHeight
  }];

  while (cells.length < cellCount) {
    const current = cells.shift();
    if (current.height > current.width) {
      // 沿高度方向拆分
      const halfHeight = current.height / 2;
      cells.push({
        xOffset: current.xOffset,
        yOffset: current.yOffset,
        width: current.width,
        height: halfHeight
      });
      cells.push({
        xOffset: current.xOffset,
        yOffset: current.yOffset + halfHeight,
        width: current.width,
        height: halfHeight
      });
    } else {
      // 沿宽度方向拆分
      const halfWidth = current.width / 2;
      cells.push({
        xOffset: current.xOffset,
        yOffset: current.yOffset,
        width: halfWidth,
        height: current.height
      });
      cells.push({
        xOffset: current.xOffset + halfWidth,
        yOffset: current.yOffset,
        width: halfWidth,
        height: current.height
      });
    }
  }
  return cells;
}

// 调用示例
const cellList = generateCells(6, 400, 600);
// 遍历绘制所有单元格
cellList.forEach(cell => {
  draw(cell.xOffset, cell.yOffset, cell.width, cell.height);
});

内容的提问来源于stack exchange,提问作者grabury

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:42:28