2. 圆弧插补基础实现
任务目标
实现二维平面圆弧插补算法,支持顺时针(CW)与逆时针(CCW)方向,输入圆心、半径、起始角与终止角,输出离散插补点,并验证所有插补点到圆心的距离(半径)保持恒定。
实现思路
采用角度增量法:将圆弧按固定角度步长Δθ离散化,从起始角逐步累加至终止角,每个角度对应一个插补点。方向由direction参数控制(1为CCW,-1为CW)。核心公式为:
x = cx + r·cos(θ)
y = cy + r·sin(θ)
完整代码
import math
def arc_interpolate(cx, cy, r, start_angle, end_angle, direction=1, step_angle=0.05):
"""
圆弧插补:角度增量法
:param cx, cy: 圆心坐标
:param r: 圆弧半径
:param start_angle: 起始角(弧度)
:param end_angle: 终止角(弧度)
:param direction: 1=逆时针(CCW), -1=顺时针(CW)
:param step_angle: 插补步长(弧度)
:return: 插补点列表 [(x1,y1), (x2,y2), ...]
"""
# 计算总角度增量(带方向)
delta = (end_angle - start_angle) * direction
# 归一化到 [-2π, 2π],取最短路径
delta = math.fmod(delta, 2 * math.pi)
if delta == 0:
delta = 2 * math.pi * direction # 整圆
# 确定步数(向上取整保证覆盖终点)
steps = max(1, int(math.ceil(abs(delta) / step_angle)))
actual_step = delta / steps # 实际步长(带方向)
points = []
for i in range(steps + 1):
theta = start_angle + i * actual_step
x = cx + r * math.cos(theta)
y = cy + r * math.sin(theta)
points.append((round(x, 6), round(y, 6)))
return points
def verify_radius(points, cx, cy, r, tolerance=1e-4):
"""验证所有插补点到圆心距离是否恒等于半径"""
max_dev = 0.0
for (x, y) in points:
dist = math.sqrt((x - cx) ** 2 + (y - cy) ** 2)
dev = abs(dist - r)
max_dev = max(max_dev, dev)
return max_dev < tolerance, max_dev
# ========== 最小验证闭环 ==========
if __name__ == "__main__":
# 测试1:逆时针90°圆弧(从0°到90°)
cx, cy, r = 0.0, 0.0, 10.0
pts_ccw = arc_interpolate(cx, cy, r, 0, math.pi / 2, direction=1)
ok1, dev1 = verify_radius(pts_ccw, cx, cy, r)
print(f"CCW 90°: 点数={len(pts_ccw)}, 半径最大偏差={dev1:.2e}, 通过={ok1}")
# 测试2:顺时针90°圆弧(从90°到0°)
pts_cw = arc_interpolate(cx, cy, r, math.pi / 2, 0, direction=-1)
ok2, dev2 = verify_radius(pts_cw, cx, cy, r)
print(f"CW 90°: 点数={len(pts_cw)}, 半径最大偏差={dev2:.2e}, 通过={ok2}")
# 测试3:整圆(起点=终点)
pts_full = arc_interpolate(cx, cy, r, 0, 0, direction=1)
ok3, dev3 = verify_radius(pts_full, cx, cy, r)
print(f"整圆CCW: 点数={len(pts_full)}, 半径最大偏差={dev3:.2e}, 通过={ok3}")
# 打印前5个CCW插补点供观察
print("\nCCW前5个插补点:")
for p in pts_ccw[:5]:
print(f" ({p[0]:.4f}, {p[1]:.4f})")
运行与验证
运行方式:直接执行python arc_interp.py(将上述代码保存为该文件名)。
通过条件:控制台输出中三个测试的通过=True,且半径最大偏差均小于1e-4。该偏差仅来源于浮点舍入与round(x,6)的截断误差,证明插补点严格落在目标圆弧上。
关键说明
- 方向处理:
direction=1时角度递增(CCW),-1时角度递减(CW)。delta的计算方式保证无论起止角大小,始终沿指定方向走最短弧。 - 整圆支持:当起止角相同时,
delta被设为2π·direction,实现完整圆周插补。 - 步长自适应:实际步长
actual_step由总角度除以步数得到,确保终点被精确覆盖,避免累积误差。
上图展示了圆心在原点、半径10的圆弧插补示意:红色为逆时针(0°→90°),蓝色为顺时针(90°→0°),绿色虚线标注半径恒定。插补点(红点)均匀分布在圆弧上,验证了角度增量法的正确性。