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

如何用Python将多边形分割为n个等面积子多边形?求坐标与代码

多边形等面积分割实现方案

外多边形示意图

上图为目标外多边形,需使用Python将其分割为多个等面积子多边形,并获取各子多边形的坐标。

原始多边形坐标

coordinates = [(17.436838, 78.466061), (17.433808, 78.488205), (17.415792, 78.486832), (17.412598, 78.464001)]

实现思路

  • 先计算原多边形总面积,确定每个子多边形的目标面积(总面积 ÷ 分割份数)
  • 采用扫描线逼近法:从多边形的边出发,生成平行于对边的分割线,逐步调整分割线位置,直到截取的子多边形面积接近目标值
  • 依赖shapely库完成几何计算,该库支持多边形面积计算、分割操作及坐标转换

代码实现

首先安装依赖库:

pip install shapely

分割代码:

from shapely.geometry import Polygon, LineString
from shapely.ops import split

def split_polygon_equal_area(polygon, num_parts):
    total_area = polygon.area
    target_area = total_area / num_parts
    parts = []
    remaining_polygon = polygon

    for _ in range(num_parts - 1):
        coords = list(remaining_polygon.exterior.coords)
        # 选取第一条边作为扫描起始边
        start_point, end_point = coords[0], coords[1]
        t = 0.0
        step = 0.005
        current_area = 0.0

        while current_area < target_area and t <= 1.0:
            # 计算扫描线上的中间点
            mid_point = (
                start_point[0] + t * (end_point[0] - start_point[0]),
                start_point[1] + t * (end_point[1] - start_point[1])
            )
            # 生成平行于对边的分割线(用足够远的点模拟无限长直线)
            opposite_edge = LineString([coords[2], coords[3]])
            dx = opposite_edge.coords[1][0] - opposite_edge.coords[0][0]
            dy = opposite_edge.coords[1][1] - opposite_edge.coords[0][1]
            split_line = LineString([
                (mid_point[0] - 100 * dx, mid_point[1] - 100 * dy),
                (mid_point[0] + 100 * dx, mid_point[1] + 100 * dy)
            ])

            # 分割多边形并计算面积
            split_result = split(remaining_polygon, split_line)
            if len(split_result.geoms) == 2:
                part1, part2 = split_result.geoms
                current_area = part1.area
                # 误差控制:当面积达到目标值的95%以上时确认分割
                if current_area >= target_area * 0.95:
                    parts.append(part1)
                    remaining_polygon = part2
                    break
            t += step

    # 添加最后一部分
    parts.append(remaining_polygon)

    # 将子多边形转换为坐标列表(去除重复的闭合点)
    part_coords = []
    for part in parts:
        poly_coords = list(part.exterior.coords)[:-1]
        part_coords.append([(round(x, 6), round(y, 6)) for x, y in poly_coords])
    
    return part_coords

if __name__ == "__main__":
    # 初始化原多边形
    original_coords = [(17.436838, 78.466061), (17.433808, 78.488205), (17.415792, 78.486832), (17.412598, 78.464001)]
    original_poly = Polygon(original_coords)
    
    # 分割为2个等面积部分(可修改num_parts为任意正整数)
    num_parts = 2
    sub_polygons = split_polygon_equal_area(original_poly, num_parts)

    # 输出结果
    print("各子多边形坐标:")
    for idx, coords in enumerate(sub_polygons, 1):
        print(f"子多边形{idx}: {coords}")

注意事项

  • 代码采用近似分割逻辑,通过逐步调整扫描线位置逼近目标面积,可根据需求修改误差阈值(0.95)或步长(0.005)
  • 对于复杂不规则多边形,可优化分割线生成逻辑(如基于中轴线或垂直方向),提升分割精度
  • shapely库的split函数要求分割线必须穿过多边形内部,若出现分割失败情况,需调整分割线的生成方向

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:42:45