Bezier曲线曲面生成算法

Bezier 曲线/曲面是 CNC、机器人、矢量图形和运动规划中最常用的轨迹生成工具


一、Bezier 曲线数学本质

Bezier 曲线 = 控制点加权叠加 + Bernstein 多项式

定义式

给定 ( n+1n+1n+1 ) 个控制点 ( P0...PnP_0 \dots P_nP0...Pn ):

B(t)=∑i=0n(ni)(1−t)n−itiPi,t∈[0,1]B(t) = \sum_{i=0}^{n} \binom{n}{i}(1-t)^{n-i}t^i P_i,\quad t\in[0,1]B(t)=∑i=0n(in)(1−t)n−itiPi,t∈[0,1]

优点

  • 必过起点和终点
  • 曲线被控制多边形"包裹"
  • 连续、平滑、易求导

缺点

  • 高阶不稳定(>6 阶不建议)

二、最推荐:De Casteljau 算法

这是数值最稳定、最适合 MCU 的实现方法。

1、几何意义

在每条线段上按比例 ( t ) 取点,逐层递归,直到只剩一个点 ------ 那就是曲线上的点。

2、二维 Bezier 曲线(C 代码)

c 复制代码
typedef struct {
    float x;
    float y;
} Point2f;

Point2f bezier2(Point2f p[3], float t)
{
    Point2f q0, q1, r;

    q0.x = (1 - t) * p[0].x + t * p[1].x;
    q0.y = (1 - t) * p[0].y + t * p[1].y;

    q1.x = (1 - t) * p[1].x + t * p[2].x;
    q1.y = (1 - t) * p[1].y + t * p[2].y;

    r.x = (1 - t) * q0.x + t * q1.x;
    r.y = (1 - t) * q0.y + t * q1.y;

    return r;
}

适合 STM32 / GRBL / 运动插补


3、任意阶 De Casteljau(通用版)

c 复制代码
void bezier_casteljau(Point2f *P, int n, float t, Point2f *out)
{
    Point2f tmp[n];
    for (int i = 0; i < n; i++)
        tmp[i] = P[i];

    for (int k = 1; k <= n; k++) {
        for (int i = 0; i < n - k; i++) {
            tmp[i].x = (1 - t) * tmp[i].x + t * tmp[i + 1].x;
            tmp[i].y = (1 - t) * tmp[i].y + t * tmp[i + 1].y;
        }
    }
    *out = tmp[0];
}

复杂度 O(n²),n ≤ 6 完全没问题


三、Bezier 曲线在运动控制中的用法(重点)

1、生成轨迹点(插补)

c 复制代码
for (int i = 0; i <= 100; i++) {
    float t = i / 100.0f;
    Point2f pt = bezier2(ctrl, t);
    move_to(pt.x, pt.y);
}

替代直线插补

用于 CNC 圆角、平滑路径

可用于 速度规划(对 t 求导)


2、一阶导数

B′(t)=n∑i=0n−1(Pi+1−Pi)Bi,n−1(t)B'(t) = n\sum_{i=0}^{n-1}(P_{i+1}-P_i)B_{i,n-1}(t)B′(t)=n∑i=0n−1(Pi+1−Pi)Bi,n−1(t)

c 复制代码
Point2f bezier_velocity(Point2f p[3], float t)
{
    Point2f v;
    v.x = 2 * ((1 - t)*(p[1].x - p[0].x) + t*(p[2].x - p[1].x));
    v.y = 2 * ((1 - t)*(p[1].y - p[0].y) + t*(p[2].y - p[1].y));
    return v;
}

四、Bezier 曲面(CNC / 3D 打印核心)

1、双三次 Bezier 曲面

S(u,v)=∑i=0n∑j=0mBin(u)Bjm(v)PijS(u,v)=\sum_{i=0}^{n}\sum_{j=0}^{m}B_i^n(u)B_j^m(v)P_{ij}S(u,v)=∑i=0n∑j=0mBin(u)Bjm(v)Pij

2、直观理解

  • u 方向一条 Bezier
  • v 方向一条 Bezier
  • 网格控制点 → 曲面

3、代码

c 复制代码
Point3f bezier_surface(Point3f P[4][4], float u, float v)
{
    Point3f pu[4];

    for (int i = 0; i < 4; i++)
        pu[i] = bezier_casteljau(P[i], 4, u);

    return bezier_casteljau(pu, 4, v);
}

参考代码 Bezier曲线曲面生成算法 www.youwenfan.com/contentcsu/70189.html

五、工程落地建议(STM32 / GRBL)

只用 3~4 阶 Bezier

预计算 t 表(节省 CPU)

固定点运算(Q16.16)

曲线 → 微小直线段(G-code 兼容)

用于:

  • 圆弧平滑
  • S 形加减速
  • 拐角过渡
  • 机器人末端轨迹

六、常见坑

问题 解决方案
高阶震荡 拆成多段低阶
计算量大 查表 + DMA
不光滑 保证 C¹ 连续
轨迹超界 限制控制点范围
相关推荐
平行侠2 小时前
024多精度大整数 - 突破硬件精度限制的任意精度运算
数据结构·算法
IronMurphy2 小时前
【算法四十五】139. 单词拆分
算法
洛水水3 小时前
【力扣100题】32.将有序数组转换为二叉搜索树
数据结构·算法·leetcode
如竟没有火炬3 小时前
用队列实现栈
开发语言·数据结构·python·算法·leetcode·深度优先
云栖梦泽在4 小时前
AI安全入门:AI模型泄露的风险与防护措施
人工智能·算法·动态规划
水木流年追梦4 小时前
大模型入门-应用篇3-Agent智能体
开发语言·python·算法·leetcode·正则表达式
洛水水5 小时前
【力扣100题】31.二叉树的层序遍历
算法·leetcode·职场和发展
君义_noip5 小时前
CSP-S 2025 入门级 第一轮(初赛) 完善程序(1)
c++·算法·信息学奥赛·初赛·csp 第一轮
洛水水5 小时前
【力扣100题】41.爬楼梯
算法·leetcode·职场和发展