1. 直线插补
任务目标
实现第一象限直线逐点比较法插补算法。给定直线起点与终点坐标,算法逐点计算并输出从起点到终点的插补点序列,并将插补轨迹与理论直线对比绘制。
算法原理
逐点比较法每步根据当前点与理论直线的偏差决定进给方向。设直线起点为原点,终点为 (xe, ye),当前点为 (xi, yi),定义偏差:
Fi = xi·ye − yi·xe
- Fi ≥ 0:向 +X 进给一步,xi+1 = xi + 1,Fi+1 = Fi − ye
- Fi < 0:向 +Y 进给一步,yi+1 = yi + 1,Fi+1 = Fi + xe
总步数 N = xe + ye,迭代 N 次后到达终点。
完整实现
import matplotlib.pyplot as plt
def line_interpolation_dda(xe, ye):
"""
第一象限直线逐点比较法插补
参数: xe, ye — 终点坐标(起点为原点)
返回: 插补点列表 [(x0,y0), (x1,y1), ...]
"""
if xe <= 0 or ye <= 0:
raise ValueError("本实现仅适用于第一象限,xe和ye必须为正整数")
points = [(0, 0)]
x, y = 0, 0
F = 0
total_steps = xe + ye
for _ in range(total_steps):
if F >= 0:
x += 1
F -= ye
else:
y += 1
F += xe
points.append((x, y))
return points
def plot_trajectory(points, xe, ye):
"""绘制插补轨迹与理论直线"""
xs = [p[0] for p in points]
ys = [p[1] for p in points]
plt.figure(figsize=(6, 6))
# 插补轨迹(阶梯线)
plt.plot(xs, ys, 'b-o', markersize=4, linewidth=1.5, label='插补轨迹')
# 理论直线
plt.plot([0, xe], [0, ye], 'r--', linewidth=2, label='理论直线')
plt.scatter([xe], [ye], color='g', s=80, zorder=5, label='终点')
plt.xlabel('X')
plt.ylabel('Y')
plt.title(f'逐点比较法直线插补 (终点: {xe},{ye})')
plt.grid(True, linestyle='--', alpha=0.6)
plt.legend()
plt.axis('equal')
plt.show()
if __name__ == "__main__":
# 示例:终点 (8, 6)
xe, ye = 8, 6
pts = line_interpolation_dda(xe, ye)
print(f"插补点序列(共{len(pts)}个点):")
for p in pts:
print(f" ({p[0]}, {p[1]})")
plot_trajectory(pts, xe, ye)
运行方式
- 安装依赖:
pip install matplotlib - 将代码保存为
dda_line.py,运行:python dda_line.py
验证方法
- 程序输出从 (0,0) 到 (8,6) 的完整插补点序列,共 8+6=14 步,末点为 (8,6)。
- 弹出图形窗口,蓝色阶梯线从原点出发,最终到达绿色终点;红色虚线为理论直线,蓝色轨迹应始终贴近红色直线且不越过终点。
- 可修改
xe, ye为其他正整数(如 5, 9)验证算法通用性,输出点数始终为 xe+ye+1。
预期输出(示例)
插补点序列(共15个点):
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(3, 1)
(4, 1)
(4, 2)
(5, 2)
(6, 2)
(6, 3)
(7, 3)
(7, 4)
(8, 4)
(8, 5)
(8, 6)
常见问题
- 输入非正整数:算法基于逐单位进给,坐标必须为正整数;若需处理非整数坐标,需改用DDA或Bresenham算法。
- 偏差计算溢出:xe、ye较大时F值可能超出整数范围,Python无此问题;若移植到C等语言需使用长整型。
- 轨迹偏离理论线:逐点比较法最大偏差不超过1个脉冲当量,属正常现象;若偏离过大,检查偏差递推公式是否正确。