3. 圆弧插补
任务目标
给定圆弧的起点、终点和圆心坐标,以及顺/逆时针方向标志,实现圆弧插补:将圆弧离散为一系列插补点,供后续运动控制使用。本案例聚焦于二维平面圆弧,输出各插补点坐标及对应的弓高误差。
核心算法
采用时间分割法(插补周期固定),按以下步骤实现:
- 由起点、终点、圆心计算半径、起始角、终止角及圆弧方向;
- 根据插补周期和进给速度计算每周期角步距;
- 从起始角开始,按方向逐步累加角度,计算插补点坐标;
- 最后一点强制等于终点,避免累积误差。
关键完整代码
import math
def arc_interpolate(start, end, center, clockwise, feed_rate=100.0, cycle_time=0.001):
"""
圆弧插补(二维平面)
:param start: (x, y) 起点
:param end: (x, y) 终点
:param center: (cx, cy) 圆心
:param clockwise: True=顺时针, False=逆时针
:param feed_rate: 进给速度 mm/s
:param cycle_time: 插补周期 s
:return: 插补点列表 [(x, y), ...],含起点和终点
"""
sx, sy = start
ex, ey = end
cx, cy = center
# 1. 半径与角度
r = math.hypot(sx - cx, sy - cy)
start_angle = math.atan2(sy - cy, sx - cx)
end_angle = math.atan2(ey - cy, ex - cx)
# 2. 计算总角位移(考虑方向)
if clockwise:
# 顺时针:角度递减
delta_angle = start_angle - end_angle
if delta_angle < 0:
delta_angle += 2 * math.pi
else:
# 逆时针:角度递增
delta_angle = end_angle - start_angle
if delta_angle < 0:
delta_angle += 2 * math.pi
# 3. 角步距
arc_length = r * delta_angle
num_steps = max(1, int(arc_length / (feed_rate * cycle_time)))
angle_step = delta_angle / num_steps
# 4. 生成插补点
points = []
for i in range(num_steps + 1):
angle = start_angle + angle_step * i if not clockwise else start_angle - angle_step * i
x = cx + r * math.cos(angle)
y = cy + r * math.sin(angle)
points.append((round(x, 6), round(y, 6)))
# 5. 强制终点精确
points[-1] = (round(ex, 6), round(ey, 6))
return points
# 最小验证示例
if __name__ == "__main__":
# 逆时针半圆:起点(0,0),终点(2,0),圆心(1,0)
pts_ccw = arc_interpolate((0, 0), (2, 0), (1, 0), clockwise=False)
print("逆时针半圆点数:", len(pts_ccw))
print("首点:", pts_ccw[0], "末点:", pts_ccw[-1])
# 顺时针四分之一圆:起点(1,0),终点(0,1),圆心(0,0)
pts_cw = arc_interpolate((1, 0), (0, 1), (0, 0), clockwise=True)
print("顺时针1/4圆点数:", len(pts_cw))
print("首点:", pts_cw[0], "末点:", pts_cw[-1])
# 验证所有点均在圆上(半径误差)
r_test = math.hypot(1, 0) # 半径=1
max_err = max(abs(math.hypot(x, y) - r_test) for x, y in pts_cw)
print("顺时针圆弧最大半径误差:", max_err)
运行与验证
运行方式:直接执行 python arc_interpolate.py(需Python 3.6+,无第三方依赖)。
通过条件:
- 逆时针半圆首点为(0,0)、末点为(2,0),点数大于10;
- 顺时针1/4圆首点为(1,0)、末点为(0,1);
- 所有插补点到圆心的距离与半径之差小于1e-5(即代码输出的最大半径误差极小);
- 相邻点间距近似等于
feed_rate × cycle_time = 0.1mm(可自行抽查)。
关键说明
- 角度计算使用
atan2,自动处理象限;方向通过角度增减方向区分,无需额外分支判断跨象限问题。 - 当起点与终点重合时,
delta_angle为0,函数返回单点(起点),实际应用中应预先判断整圆情况。 - 插补周期与进给速度的乘积决定步长,步长过大时弓高误差增大,可据此调整参数。
上图示意两种方向的圆弧插补几何关系:逆时针半圆从起点经上方弧线到达终点,顺时针1/4圆从起点经右侧弧线到达终点。实际插补点沿弧线均匀分布,步长由进给速度与插补周期决定。