4. 圆弧插补算法:逐点比较法、DDA与角度增量法

圆弧插补,说白了就是让刀具走一段完美的圆弧。你想想看,数控系统里直线好办,但圆弧就有点意思了——怎么用离散的脉冲拼出连续的弧线?

我个人习惯把圆弧插补分成三类来理解:逐点比较法、DDA法、角度增量法。每种方法都有自己的脾气,我在项目里都踩过坑,今天一次性给你讲透。

4.1 逐点比较法圆弧插补

这个方法最直观。它的核心思想就一句话:每走一步,判断当前位置在圆弧的哪一侧

偏差计算公式很简单:

F = X² + Y² - R²

如果 F > 0,点在圆外;F < 0,点在圆内;F = 0,正好在圆上。

嗯,这里要注意:不同象限的进给方向不一样。我刚开始做的时候,就因为这个象限判断写错过,结果圆弧跑成了椭圆……

逐点比较法核心步骤:

  1. 计算偏差 F
  2. 根据 F 的正负决定进给方向
  3. 更新坐标和偏差
  4. 判断是否到达终点

Python 实现如下:

def point_by_point_arc(x0, y0, x1, y1, r, quadrant=1):
    """
    逐点比较法圆弧插补
    quadrant: 象限 1-4
    """
    x, y = x0, y0
    path = [(x, y)]
    
    while True:
        # 计算偏差
        F = x*x + y*y - r*r
        
        # 根据象限和偏差决定进给方向
        if quadrant == 1:
            if F >= 0:
                x -= 1  # 向圆内走
            else:
                y += 1  # 向圆外走
        elif quadrant == 2:
            if F >= 0:
                y += 1
            else:
                x += 1
        # ... 其他象限类似
        
        path.append((x, y))
        
        # 到达终点判断
        if abs(x - x1) < 0.5 and abs(y - y1) < 0.5:
            break
    
    return path

我的经验:逐点比较法适合低速、高精度的场合。我曾经在雕刻机上用过,走小圆弧时效果很好,但速度一快就有点抖。原因是它每一步都要计算偏差,CPU 负担不小。

4.2 DDA 圆弧插补

DDA(数字微分分析器)法,说白了就是用积分的思想来走圆弧。它把圆弧运动分解成 X 和 Y 两个方向的速度分量。

核心公式:

ΔX = -Y * Δt
ΔY =  X * Δt

为什么会这样?因为圆弧上任意一点的切线方向,正好是 (-Y, X)。你想想看,这不就是速度方向吗?

DDA 的好处是:速度均匀,适合高速加工。我在做激光切割项目时,就用的 DDA 法,走大圆弧特别顺滑。

def dda_arc(x0, y0, r, start_angle, end_angle, steps=100):
    """
    DDA 圆弧插补
    """
    x, y = x0 + r * math.cos(start_angle), y0 + r * math.sin(start_angle)
    path = [(x, y)]
    
    dt = (end_angle - start_angle) / steps
    
    for _ in range(steps):
        # DDA 积分
        dx = -y * dt
        dy =  x * dt
        
        x += dx
        y += dy
        
        path.append((x, y))
    
    return path

注意:DDA 法有个坑——累积误差。我曾经在跑 1000 步的圆弧时,终点偏差达到了 0.5mm。解决办法是:每走一段就做一次误差补偿,或者用双精度浮点数。

4.3 角度增量法

这个方法最直接,也最好理解。就是把圆弧按角度等分,然后计算每个点的坐标。

公式:

X = R * cos(θ)
Y = R * sin(θ)

θ 从起始角到终止角,每次增加一个固定步长。

角度增量法的优点是:代码简单,容易理解。但缺点也很明显——如果步长太大,圆弧会变成多边形;步长太小,计算量又大。

def angle_increment_arc(x0, y0, r, start_angle, end_angle, step_angle=0.01):
    """
    角度增量法圆弧插补
    """
    path = []
    theta = start_angle
    
    while theta <= end_angle:
        x = x0 + r * math.cos(theta)
        y = y0 + r * math.sin(theta)
        path.append((x, y))
        theta += step_angle
    
    return path

我的建议:角度增量法适合做离线编程,比如生成 G 代码。但在实时插补中,我一般不推荐——因为它的步长固定,无法根据曲率自适应调整。

4.4 三种方法对比

方法 精度 速度 适用场景
逐点比较法 低速高精度加工
DDA 法 高速连续加工
角度增量法 离线编程、教学演示

4.5 核心逻辑流程图

圆弧插补算法核心逻辑 输入圆弧参数 选择插补方法 逐点比较法 计算偏差 F DDA 法 积分计算 ΔX, ΔY 角度增量法 等分角度计算坐标 输出插补路径

这张图把三种方法的流程串起来了。你从输入参数开始,根据需求选择方法,然后走对应的计算逻辑,最后输出路径。我在实际项目中,经常根据加工速度动态切换方法——低速用逐点比较法,高速用 DDA 法。

避坑指南:

  • 我曾经在 DDA 法里忘记做误差补偿,结果跑出来的圆弧不闭合
  • 逐点比较法要注意象限切换,否则方向会反
  • 角度增量法的步长不要设太大,否则圆弧会变成多边形

好了,三种圆弧插补方法就讲到这里。代码我都跑过,可以直接用。你试试看,有问题随时找我。

专注资料整理