4. 逐点比较法(二):圆弧插补原理、象限处理、终点判别

好,咱们接着聊逐点比较法。上一章讲了直线插补,说白了就是走直线。那圆弧呢?说白了就是走圆。你可能会想,走圆比走直线复杂多了吧?嗯,确实复杂一些,但核心思想没变——还是那四个字:逐点比较。

我个人习惯把圆弧插补理解成“追着圆弧跑”。刀具每走一步,我就看看它是在圆弧里面还是外面,然后决定下一步往哪走。就这么简单。

4.1 圆弧插补的基本原理

先想一个问题:怎么判断一个点是在圆弧上、圆弧内还是圆弧外?

假设我们要加工第一象限的逆圆弧。圆心在原点,半径为R。当前刀具位置是P(x, y)。那么:

  • 如果 x² + y² - R² = 0,点在圆弧上
  • 如果 x² + y² - R² > 0,点在圆弧外
  • 如果 x² + y² - R² < 0,点在圆弧内

这个差值,我们就叫它偏差值,记作F。

核心公式:

F = x² + y² - R²

这就是圆弧插补的“判据”。

那下一步怎么走?对于第一象限的逆圆弧:

  • F ≥ 0:点在圆弧外或圆弧上,向圆内走一步(-X方向)
  • F < 0:点在圆弧内,向圆外走一步(+Y方向)

你想想看,这个逻辑是不是很直观?偏外了就往里收,偏内了就往外扩。就像开车走弯道,方向偏了就得修正。

4.2 递推公式——别每次都算平方

这里有个坑。如果每走一步都算一次 x² + y²,计算量太大了。我在项目中遇到过这种情况,早期用8位单片机做插补,算一次平方要几十个指令周期,根本跑不动。

所以我们要用递推公式。什么意思?就是利用上一步的偏差值,推算出下一步的偏差值。

假设当前点P(x, y),偏差F = x² + y² - R²。

情况一:向-X方向走一步

新位置:x' = x - 1, y' = y

新偏差:F' = (x-1)² + y² - R² = (x² - 2x + 1) + y² - R² = F - 2x + 1

情况二:向+Y方向走一步

新位置:x' = x, y' = y + 1

新偏差:F' = x² + (y+1)² - R² = x² + (y² + 2y + 1) - R² = F + 2y + 1

我的小技巧:写代码时,把这两个递推公式写成宏或者内联函数。别写成函数调用,嵌入式环境里函数调用开销不小。

4.3 象限处理——别只盯着第一象限

嗯,这里要注意。实际加工中,圆弧可能出现在任意象限。不同象限的进给方向是不一样的。

我整理了一张表,你直接拿去用:

圆弧类型 象限 F ≥ 0 进给方向 F < 0 进给方向
逆圆弧 第一象限 -X +Y
第二象限 +Y +X
第三象限 +X -Y
第四象限 -Y -X
顺圆弧 第一象限 -Y +X
第二象限 -X -Y
第三象限 +Y -X
第四象限 +X +Y

看着有点乱是吧?其实有规律。你记住一句话:逆圆弧往圆心方向走,顺圆弧往远离圆心方向走。再结合象限位置,就能推出来。

我曾经踩过的坑:象限切换时,偏差值要重新计算!不能直接用递推公式跨象限。因为递推公式假设你在同一个象限内运动,跨象限后坐标符号变了,递推公式就不准了。

4.4 终点判别——怎么知道走完了?

圆弧插补的终点判别比直线复杂一些。直线插补可以用总步数来判断,但圆弧不行——因为圆弧可能走90度、180度,也可能走任意角度。

常用的方法有三种:

  1. 总步数法:提前算好圆弧上需要走多少步,每走一步减1,减到0就停。
  2. 坐标比较法:每走一步,比较当前位置是否到达终点坐标。
  3. 偏差值法:当偏差值接近0且位置接近终点时,认为插补结束。

我个人最推荐总步数法。为什么?简单、可靠、不依赖浮点运算。

总步数怎么算?假设圆弧起点(xs, ys),终点(xe, ye):

总步数 = |xe - xs| + |ye - ys|

注意,这个公式只适用于45度倍数的圆弧。对于任意角度,需要根据圆弧长度和步长来算。

代码示例(C语言风格):

// 圆弧插补主循环
void arc_interpolate(int xs, int ys, int xe, int ye, int R, int dir) {
    int x = xs, y = ys;
    int F = x*x + y*y - R*R;
    int steps = abs(xe - xs) + abs(ye - ys);  // 总步数
    
    while (steps > 0) {
        if (F >= 0) {
            // 向圆内走
            x--;  // 第一象限逆圆弧示例
            F = F - 2*x + 1;
        } else {
            // 向圆外走
            y++;
            F = F + 2*y + 1;
        }
        steps--;
        output_step(x, y);  // 输出一步
    }
}

4.5 知识体系总览

下面这张图,把圆弧插补的核心逻辑串起来了。你一看就明白:

圆弧插补核心逻辑 读取起点、终点、半径 计算初始偏差 F F ≥ 0 ? (在圆外/上) 向圆内走一步 向圆外走一步 更新偏差 F 和位置 终点到了吗? 未到,继续 结束

这张图把整个流程串起来了。你顺着箭头走一遍,就能理解圆弧插补的完整逻辑。

4.6 实际项目中的几点建议

最后,分享几个我在实际项目中积累的经验:

  • 速度匹配:圆弧插补时,X轴和Y轴的速度要匹配好。不然走出来的圆弧会变形。我一般用“时间分割法”来保证速度同步。
  • 过象限处理:圆弧过象限时,进给方向会突变。这时候要平滑过渡,不然机床会抖一下。我的做法是在象限边界处做加减速处理。
  • 误差累积:递推公式虽然快,但会有误差累积。走大圆弧时,建议每隔一段距离重新计算一次偏差,把误差“清零”。

一个小技巧:调试圆弧插补时,别直接上机床。先用软件模拟,把每一步的坐标打印出来,画成图看看。我当年调试时,就是靠这个办法发现了一个象限判断的bug。

好了,圆弧插补的原理、象限处理、终点判别,咱们都过了一遍。说白了就是:算偏差、判方向、走一步、更新偏差、判终点。这五个步骤循环,就能走出漂亮的圆弧。


公众号:蓝海资料掘金营,微信deep3321