2. 直线插补

任务目标

使用数字微分分析器(DDA)法实现直线插补,支持任意象限直线,输出各轴步进脉冲序列,并通过仿真验证插补轨迹与理论直线的一致性。

核心原理

DDA直线插补将直线位移分解为各轴增量,通过累加器溢出产生脉冲。设终点坐标为(Xe, Ye),取累加器位数为n(通常n≥2),则X轴步进当量Δx = Xe / 2ⁿ,Y轴步进当量Δy = Ye / 2ⁿ。每个插补周期内,各轴累加器分别累加对应增量,当累加值超过2ⁿ时产生一个脉冲并减去2ⁿ。插补总周期数为2ⁿ,保证到达终点。

实现代码

import matplotlib.pyplot as plt

def dda_line(xe, ye, n=8):
    """
    DDA直线插补,支持任意象限
    返回: x_pulses, y_pulses (各轴脉冲序列,1表示正向,-1表示反向)
    """
    # 取值计算步数
    steps = 2 ** n
    dx = abs(xe)
    dy = abs(ye)
    
    # 方向标志
    sx = 1 if xe >= 0 else -1
    sy = 1 if ye >= 0 else -1
    
    # 累加器
    rx = 0  # X余数累加器
    ry = 0  # Y余数累加器
    
    # 脉冲序列
    x_pulses = []
    y_pulses = []
    
    # 当前坐标(用于轨迹记录)
    x, y = 0, 0
    traj_x = [0]
    traj_y = [0]
    
    for _ in range(steps):
        # 累加增量
        rx += dx
        ry += dy
        
        # 溢出判断
        px = 0
        py = 0
        if rx >= steps:
            rx -= steps
            px = sx
            x += sx
        if ry >= steps:
            ry -= steps
            py = sy
            y += sy
        
        x_pulses.append(px)
        y_pulses.append(py)
        traj_x.append(x)
        traj_y.append(y)
    
    return x_pulses, y_pulses, traj_x, traj_y

def simulate_and_plot(xe, ye, n=8):
    """仿真并绘制轨迹"""
    x_pulses, y_pulses, traj_x, traj_y = dda_line(xe, ye, n)
    
    # 计算终点误差
    end_x = sum(x_pulses)
    end_y = sum(y_pulses)
    print(f"终点坐标: ({end_x}, {end_y}), 目标: ({xe}, {ye})")
    print(f"X脉冲数: {sum(1 for p in x_pulses if p != 0)}, "
          f"Y脉冲数: {sum(1 for p in y_pulses if p != 0)}")
    
    # 绘制轨迹
    plt.figure(figsize=(6, 6))
    plt.plot(traj_x, traj_y, 'b-', linewidth=1, label='DDA轨迹')
    plt.plot([0, xe], [0, ye], 'r--', linewidth=1.5, label='理论直线')
    plt.scatter(traj_x, traj_y, s=8, c='blue', alpha=0.6)
    plt.scatter([xe], [ye], c='red', s=50, zorder=5)
    plt.grid(True, alpha=0.3)
    plt.axis('equal')
    plt.legend()
    plt.title(f'DDA直线插补 (终点: {xe}, {ye})')
    plt.xlabel('X轴脉冲数')
    plt.ylabel('Y轴脉冲数')
    plt.show()

# 测试各象限直线
if __name__ == "__main__":
    # 第一象限
    simulate_and_plot(15, 8)
    # 第二象限
    simulate_and_plot(-12, 7)
    # 第三象限
    simulate_and_plot(-10, -6)
    # 第四象限
    simulate_and_plot(9, -5)

运行与验证

环境依赖:Python 3.x,matplotlib库(pip install matplotlib)。

运行方式:直接执行脚本,将依次显示四个象限直线的插补仿真图。

验证方法:

  1. 观察控制台输出:终点坐标应与目标坐标完全一致(如第一象限输出终点(15, 8));
  2. 检查图形:蓝色阶梯状轨迹应始终贴近红色理论直线,且最终到达红色终点标记;
  3. 验证脉冲序列:X轴总脉冲数应等于|Xe|,Y轴总脉冲数应等于|Ye|,脉冲方向与象限符号一致。

通过标准:四个象限的终点坐标均精确匹配,轨迹偏差不超过1个脉冲当量,且脉冲总数正确。

常见问题

  • 累加器位数n的选择:n过小会导致步距大、轨迹粗糙;n过大则插补周期长。一般取n=8~16,使2ⁿ ≥ max(|Xe|, |Ye|)即可。
  • 象限处理:本实现通过符号标志sx、sy控制脉冲方向,累加时使用值,确保各象限行为一致。
  • 终点精确性:DDA法在2ⁿ个周期内必然到达终点,因为每个轴累加的总量恰好等于终点坐标值。