4. 圆弧插补
任务目标
实现第一象限逆时针圆弧的逐点比较法插补。给定圆心、半径、起点与终点(均在第一象限且位于圆弧上),程序逐点计算插补坐标,输出全部插补点,并绘制圆弧轨迹与理想圆弧进行对比。
实现原理
逐点比较法每步通过偏差判别决定进给方向。对于第一象限逆圆,偏差函数为:
F = x² + y² − R²
- F ≥ 0:向 −X 方向进给一步(
x = x − 1),新偏差F = F − 2x + 1 - F < 0:向 +Y 方向进给一步(
y = y + 1),新偏差F = F + 2y + 1
从起点开始迭代,直到到达终点坐标为止。
完整代码
import matplotlib.pyplot as plt
import numpy as np
def bresenham_circle_interp(x0, y0, R, x_start, y_start, x_end, y_end):
"""
第一象限逆圆逐点比较法插补
输入:圆心(x0,y0),半径R,起点(x_start,y_start),终点(x_end,y_end)
返回:插补点列表 [(x, y), ...]
"""
# 将坐标平移到圆心坐标系
x = x_start - x0
y = y_start - y0
xe = x_end - x0
ye = y_end - y0
points = [(x + x0, y + y0)] # 保存原始坐标系下的点
# 偏差初值
F = x * x + y * y - R * R
# 迭代直到到达终点
while True:
if F >= 0:
# 向 -X 方向进给
x -= 1
F = F - 2 * x - 1 # 注意:x已更新,用新x计算
else:
# 向 +Y 方向进给
y += 1
F = F + 2 * y + 1 # 注意:y已更新,用新y计算
points.append((x + x0, y + y0))
# 到达终点判断
if x == xe and y == ye:
break
return points
# ========== 参数设置 ==========
x0, y0 = 0, 0 # 圆心
R = 10 # 半径
x_start, y_start = 10, 0 # 起点 (R, 0)
x_end, y_end = 0, 10 # 终点 (0, R)
# ========== 执行插补 ==========
interp_points = bresenham_circle_interp(x0, y0, R, x_start, y_start, x_end, y_end)
# ========== 输出插补点 ==========
print("插补点坐标:")
for i, (px, py) in enumerate(interp_points):
print(f"第{i:2d}步: ({px:3d}, {py:3d})")
# ========== 绘制结果 ==========
xs = [p[0] for p in interp_points]
ys = [p[1] for p in interp_points]
# 理想圆弧(用于对比)
theta = np.linspace(0, np.pi / 2, 100)
ideal_x = x0 + R * np.cos(theta)
ideal_y = y0 + R * np.sin(theta)
plt.figure(figsize=(6, 6))
plt.plot(ideal_x, ideal_y, 'b-', linewidth=1, label='理想圆弧')
plt.plot(xs, ys, 'r.-', markersize=4, linewidth=0.8, label='插补轨迹')
plt.plot(x0, y0, 'k+', markersize=10, label='圆心')
plt.plot(x_start, y_start, 'go', label='起点')
plt.plot(x_end, y_end, 'mo', label='终点')
plt.gca().set_aspect('equal')
plt.grid(True, linestyle='--', alpha=0.6)
plt.legend()
plt.title('第一象限逆圆逐点比较法插补')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
运行方式
- 安装依赖:
pip install matplotlib numpy - 将代码保存为
circle_interp.py,运行python circle_interp.py
验证方法
- 程序输出从 (10, 0) 到 (0, 10) 的整数坐标点序列,首点为起点,末点为终点。
- 每个输出点应满足
x² + y²接近 100(偏差不超过进给步长带来的最大误差约 1.5)。 - 图中红色插补轨迹应沿蓝色理想圆弧从起点逆时针走向终点,且轨迹点全部位于第一象限。
- 可通过修改
x_start, y_start, x_end, y_end验证其他第一象限逆圆弧(需保证起点终点在半径为 R 的圆上)。
预期输出(前5步)
第 0步: (10, 0)
第 1步: ( 9, 0)
第 2步: ( 9, 1)
第 3步: ( 8, 1)
第 4步: ( 8, 2)
第 5步: ( 7, 2)
...
常见问题
- 偏差更新公式中的符号:代码中先更新坐标再计算新偏差,因此
F = F − 2x − 1中的 x 是更新后的值,与理论推导中先算偏差再进给的写法等价。 - 终点判断:使用精确坐标相等判断。若终点坐标非整数或不在圆上,需改用误差容限判断。
- 适用范围:本实现仅针对第一象限逆圆。其他象限或顺圆需修改进给方向与偏差更新规则。