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

如何用与多边形最长边平行的等距直线填充多边形?

多边形内生成平行于最长边的等距直线通用解决方案

核心思路

要解决这个问题,关键是基于最长边的法向量方向生成等距直线,再通过直线与多边形边的交点确定内部线段,步骤如下:

  • 确定最长边的方向与法向量
  • 计算多边形在法向量方向上的投影范围,确定直线生成区间
  • 生成每条平行直线的方程
  • 求直线与多边形的所有交点,筛选出有效线段

代码实现(通用版)

import matplotlib.pyplot as plt
import numpy as np
from shapely.geometry import LineString, Polygon
from shapely.ops import split

def longest_side(points):
    """返回最长边的两个端点及长度"""
    max_len = 0
    longest = None
    n = len(points)
    for i in range(n):
        p1 = np.array(points[i])
        p2 = np.array(points[(i+1)%n])  # 处理闭合多边形的最后一条边
        length = np.linalg.norm(p1 - p2)
        if length > max_len:
            max_len = length
            longest = (p1, p2)
    return longest

def generate_parallel_lines(polygon_points, spacing):
    """生成多边形内部与最长边平行的等距直线线段"""
    # 1. 创建Shapely多边形对象(处理闭合、顶点顺序问题)
    poly = Polygon(polygon_points)
    if not poly.is_valid:
        raise ValueError("输入的多边形无效,请检查顶点顺序或是否自交")
    
    # 2. 获取最长边及方向、法向量
    p1, p2 = longest_side(polygon_points)
    dir_vec = p2 - p1  # 最长边的方向向量
    # 计算单位法向量(垂直于最长边的方向,用于偏移生成平行直线)
    norm_vec = np.array([-dir_vec[1], dir_vec[0]])
    norm_vec = norm_vec / np.linalg.norm(norm_vec)
    
    # 3. 计算多边形所有顶点在法向量方向上的投影,确定偏移范围
    projections = [np.dot(np.array(p), norm_vec) for p in polygon_points]
    min_proj = min(projections)
    max_proj = max(projections)
    
    # 4. 生成等距平行直线
    line_segments = []
    # 从最小投影到最大投影,按间距生成每条直线的偏移量
    for offset in np.arange(min_proj, max_proj + spacing, spacing):
        # 构造平行于最长边的直线:沿法向量偏移offset的直线
        # 取最长边的两个端点分别沿法向量偏移offset,得到直线上的两个点
        line_p1 = p1 + offset * norm_vec
        line_p2 = p2 + offset * norm_vec
        line = LineString([line_p1, line_p2])
        
        # 5. 求直线与多边形的交点,得到内部线段
        intersection = poly.intersection(line)
        if intersection.geom_type == 'LineString':
            coords = list(intersection.coords)
            line_segments.append(coords)
        elif intersection.geom_type == 'MultiLineString':
            for seg in intersection.geoms:
                line_segments.append(list(seg.coords))
    
    return line_segments

if __name__ == "__main__":
    # 测试多边形顶点(闭合)
    points = ([0, 8], [2, 10], [10, 4], [10, 0], [0, 8])
    
    # 生成平行直线线段
    segments = generate_parallel_lines(points, spacing=1)
    
    # 绘制多边形
    x = [p[0] for p in points]
    y = [p[1] for p in points]
    plt.plot(x, y, 'ro-', label='多边形')
    
    # 绘制内部平行直线
    for seg in segments:
        seg_x = [p[0] for p in seg]
        seg_y = [p[1] for p in seg]
        plt.plot(seg_x, seg_y, 'b-')
    
    plt.axis('scaled')
    plt.legend()
    plt.show()

关键细节说明

  • 使用Shapely库简化几何计算:无需手动实现直线与多边形的交点逻辑,Shapely的intersection方法可以直接得到直线在多边形内部的线段,避免了复杂的边界判断。
  • 法向量方向的正确性:法向量是垂直于最长边的方向,沿这个方向偏移才能生成等距的平行直线,单位化后偏移量的单位就是实际的间距。
  • 处理多边形有效性:先检查多边形是否有效(非自交、顶点顺序正确),避免后续计算出错。
  • 覆盖整个多边形范围:通过顶点在法向量上的投影极值,确保生成的直线覆盖多边形的全部区域,不会遗漏或超出。

适配任意多边形的注意事项

  • 输入的多边形顶点必须是闭合的(最后一个顶点和第一个顶点相同),如果不闭合,代码中可以自动补充。
  • 支持简单多边形(非自交),如果是自交多边形,需要先处理为简单多边形再进行计算。
  • 间距参数可以根据需求调整,注意如果间距过大,可能会跳过部分区域,过小则会生成过多线段。

内容的提问来源于stack exchange,提问作者Son.Dre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 05:10:55