
本文介绍如何将给定坐标范围的大正方形,按指定边长均匀划分为多个不重叠的小正方形,并以 [x1, x2, y1, y2] 格式返回所有小正方形坐标的二维数组;支持边界截断处理,自动忽略无法完整容纳小正方形的边缘区域。
本文介绍如何将给定坐标范围的大正方形,按指定边长均匀划分为多个不重叠的小正方形,并以 `[x1, x2, y1, y2]` 格式返回所有小正方形坐标的二维数组;支持边界截断处理,自动忽略无法完整容纳小正方形的边缘区域。
在图像处理、网格布局、地理围栏切片或游戏地图分块等场景中,常需将一个大矩形区域(此处特指正方形)按固定尺寸进行规则网格化切割。核心要求是:每个子区域必须是严格等大的正方形,且完全位于原始区域内——即不允许越界,也不做插值或缩放,未覆盖的边缘空白区域直接舍弃。
实现逻辑非常直观:以左下角(或左上角,取决于坐标系约定)为起点,沿 x 和 y 方向分别以 smallerSquareSide 为步长进行遍历,每次生成一个边长为 smallerSquareSide 的正方形,其坐标为:
- x 范围:[j, j + smallerSquareSide - 1]
- y 范围:[i, i + smallerSquareSide - 1]
注意循环终止条件使用 i + (smallerSquareSide - 1) <= $y2(同理 x),确保右下顶点仍在大正方形内。这是关键细节——若仅用 i <= $y2,会导致最后一个正方形超出边界。
以下是完整可运行的 PHP 示例代码:
$x1 = 1;
$x2 = 100;
$y1 = 1;
$y2 = 100;
$smallerSquareSide = 10;
$res = [];
for ($i = $y1; $i + ($smallerSquareSide - 1) <= $y2; $i += $smallerSquareSide) {
for ($j = $x1; $j + ($smallerSquareSide - 1) <= $x2; $j += $smallerSquareSide) {
$res[] = [$j, $j + $smallerSquareSide - 1, $i, $i + $smallerSquareSide - 1];
}
}
// 输出前5个示例
print_r(array_slice($res, 0, 5));
// 输出示例:
// Array (
// [0] => Array ( [0] => 1 [1] => 10 [2] => 1 [3] => 10 )
// [1] => Array ( [0] => 11 [1] => 20 [2] => 1 [3] => 10 )
// [2] => Array ( [0] => 21 [1] => 30 [2] => 1 [3] => 10 )
// [3] => Array ( [0] => 31 [1] => 40 [2] => 1 [3] => 10 )
// [4] => Array ( [0] => 41 [1] => 50 [2] => 1 [3] => 10 )
// )⚠️ 注意事项:
- 坐标系假设为「数学常规笛卡尔系」:x 向右递增,y 向上递增,且 $x1 < $x2、$y1 < $y2 均成立;
- 若输入坐标不满足该条件(如 y 轴向下增长的屏幕坐标系),需先对 y 范围做翻转适配;
- 当 smallerSquareSide 大于 $x2 - $x1 + 1 或 $y2 - $y1 + 1 时,结果为空数组,符合预期;
- 本方法不填充/补全边界空隙,如 $x2 = 104 时,x ∈ [101, 104] 区域因不足 10 单位而被跳过。
总结:该算法时间复杂度为 O(n²),其中 n 是每维可容纳的小正方形数量,空间复杂度 O(n²) 存储结果,简洁高效,适用于实时性要求不苛刻的批量分块任务。如需支持非正方形矩形块、带重叠滑动窗口或坐标系自动识别,可在本基础逻辑上扩展封装。

















