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

如何使用Python的Shapely库将不规则多边形切割为矩形?

将Shapely不规则轴对齐多边形分割为标准矩形

问题背景

我有一个150×150的画布,包含多个轴对齐的不规则Shapely多边形。其中一个示例多边形的定义如下(注:已修正为Shapely兼容的坐标元组形式):
Polygon([(140, 0), (140, 50), (140, 95), (140, 140), (95, 140), (65, 140), (65, 150), (150, 150), (150, 0), (140, 0)])

原始图形:
原始不规则多边形图形

希望将每个不规则形状分割为多个轴对齐的标准矩形,参考效果如下(红色线条为分割线):
分割后的矩形效果

所有多边形的完整定义(修正为Shapely兼容格式):

Polygon([(140, 0), (140, 50), (140, 95), (140, 140), (95, 140), (65, 140), (65, 150), (150, 150), (150, 0), (140, 0)])
Polygon([(75, 0), (75, 25), (90, 25), (90, 0), (75, 0)])
Polygon([(0, 140), (0, 150), (40, 150), (40, 145), (15, 145), (15, 140), (0, 140)])
Polygon([(25, 25), (25, 30), (30, 30), (30, 45), (40, 45), (40, 25), (25, 25)])
Polygon([(15, 35), (15, 30), (10, 30), (10, 35), (15, 35)])
Polygon([(5, 0), (5, 5), (10, 5), (10, 0), (5, 0)])

可行解决方案

针对轴对齐多边形的矩形分割需求,以下是两种实用方法:

方法1:手动实现坐标网格分割

利用多边形顶点的坐标生成分割线,切割出符合要求的矩形:

  1. 提取多边形所有顶点的x、y坐标,去重后排序,得到垂直和水平方向的分割线;
  2. 遍历相邻分割线组成的网格,生成候选矩形;
  3. 筛选出完全包含在原多边形内的矩形,即为最终分割结果。

示例代码(基于Shapely):

from shapely.geometry import Polygon, box
from shapely.ops import unary_union

def split_polygon_to_rectangles(polygon):
    # 提取所有顶点的x、y坐标
    exterior_coords = list(polygon.exterior.coords)
    unique_x = sorted({x for x, y in exterior_coords})
    unique_y = sorted({y for x, y in exterior_coords})
    
    rectangles = []
    # 遍历生成所有可能的轴对齐矩形
    for x_idx in range(len(unique_x) - 1):
        for y_idx in range(len(unique_y) - 1):
            x_left, x_right = unique_x[x_idx], unique_x[x_idx+1]
            y_bottom, y_top = unique_y[y_idx], unique_y[y_idx+1]
            current_rect = box(x_left, y_bottom, x_right, y_top)
            # 只保留完全在原多边形内的矩形
            if polygon.contains(current_rect):
                rectangles.append(current_rect)
    
    # 校验分割结果与原多边形的一致性(可选)
    union_rects = unary_union(rectangles)
    if not polygon.almost_equals(union_rects, decimal=2):
        # 可补充处理边缘遗漏的小区域
        pass
    
    return rectangles

# 测试示例多边形
sample_poly = Polygon([(140, 0), (140, 50), (140, 95), (140, 140), (95, 140), (65, 140), (65, 150), (150, 150), (150, 0), (140, 0)])
result_rects = split_polygon_to_rectangles(sample_poly)
for i, rect in enumerate(result_rects):
    print(f"矩形 {i+1}: 边界 {rect.bounds}")

方法2:借助第三方库简化开发

如果不想手动实现逻辑,可以使用专门的多边形处理库:

  • shapely-split:扩展Shapely的分割能力,支持按自定义线条切割多边形;
  • polygontree:针对多边形的层级分割做了优化,适合处理复杂形状;
  • pyshp:结合Shapefile工具辅助坐标提取与分割。

注意事项

  • 该方案仅适用于轴对齐多边形:若多边形存在旋转,需先通过坐标变换转为轴对齐,或采用旋转矩形分割逻辑;
  • 面积校验:分割后建议对比矩形总面积与原多边形面积,避免遗漏或多余区域;
  • 性能优化:顶点过多时,可先合并相邻重复坐标,减少分割线数量,提升效率。

内容的提问来源于stack exchange,提问作者0x Empyrean

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:15:29