1. 直线插补基础

任务目标

实现一个直线插补函数,输入起点坐标 (x₀, y₀) 与终点坐标 (x₁, y₁),输出从起点到终点沿直线的插补点序列。插补点数量由步长参数决定,刀具按序列逐点移动即可形成直线轨迹。

核心实现

def linear_interpolate(start, end, step=1.0):
    """
    直线插补:在起点与终点之间生成等距插补点序列(含起点,不含终点)。
    参数:
        start: (x0, y0) 起点坐标
        end:   (x1, y1) 终点坐标
        step:  插补步长(沿直线方向的欧氏距离)
    返回:
        [(x, y), ...] 插补点列表
    """
    x0, y0 = start
    x1, y1 = end

    dx = x1 - x0
    dy = y1 - y0
    dist = (dx * dx + dy * dy) ** 0.5

    if dist == 0:
        return [(x0, y0)]

    # 计算插补点数(向上取整,保证最后一段不超过步长)
    n = int(dist / step) + 1

    points = []
    for i in range(n):
        t = i / n
        x = x0 + dx * t
        y = y0 + dy * t
        points.append((round(x, 6), round(y, 6)))

    # 显式加入终点,避免浮点误差
    points.append((x1, y1))
    return points

运行与验证

调用方式:直接调用函数并传入起点、终点与步长。

# 示例:从 (0,0) 到 (10,5),步长 2
points = linear_interpolate((0, 0), (10, 5), step=2)
for p in points:
    print(p)

预期输出(由代码逻辑直接推出):

(0, 0)
(1.788854, 0.894427)
(3.577709, 1.788854)
(5.366563, 2.683282)
(7.155417, 3.577709)
(8.944272, 4.472136)
(10, 5)

验证方法:检查输出序列中相邻点之间的欧氏距离是否均不超过步长 2,且首点为起点、末点为终点。可运行以下断言确认:

pts = linear_interpolate((0, 0), (10, 5), step=2)
assert pts[0] == (0, 0)
assert pts[-1] == (10, 5)
for i in range(len(pts) - 1):
    d = ((pts[i+1][0] - pts[i][0])**2 + (pts[i+1][1] - pts[i][1])**2) ** 0.5
    assert d <= 2.000001, f"步长超限: {d}"
print("验证通过")

若所有断言通过,说明插补点序列满足直线约束与步长约束,刀具沿该序列移动即可实现从 A 到 B 的直线运动。

X Y A(0,0) B(10,5) 步长≈2

上图展示了从 A(0,0) 到 B(10,5)、步长为 2 时的插补点分布。红色与绿色端点分别为起点与终点,蓝色圆点为中间插补点,虚线连接相邻插补点,灰色实线为理想直线轨迹。可见插补点均落在直线上且间距均匀。

常见问题

  • 步长大于总距离:函数仍会返回起点和终点两个点,刀具直接走完整个线段。
  • 浮点精度:代码对坐标做了 6 位小数舍入,避免累积误差导致末点偏移;末尾显式追加终点坐标。
  • 三维扩展:若需三维插补,将坐标元组扩展为 (x, y, z) 并同步修改距离计算即可,逻辑不变。