如何用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
相关产品推荐
相关产品推荐

