Bezier 曲线绘制器

项目概述

实现了经典的 Bezier 曲线 绘制算法,支持 2阶、3阶、4阶曲线,使用 De Casteljau 递归算法 实现。这是计算机图形学中最基础也最重要的曲线表示方法,广泛应用于字体设计、矢量图形、动画路径等领域。


📐 数学原理

De Casteljau 算法

对于 n 个控制点 P₀, P₁, …, Pₙ₋₁,曲线上的点通过递归线性插值计算:

1
B(t) = (1-t) · B₀₋ₙ₋₂(t) + t · B₁₋ₙ₋₁(t)

其中 t ∈ [0, 1] 是参数。

具体公式

二阶 Bezier(3个控制点)

1
B(t) = (1-t)² · P₀ + 2(1-t)t · P₁ + t² · P₂

三阶 Bezier(4个控制点)

1
B(t) = (1-t)³ · P₀ + 3(1-t)²t · P₁ + 3(1-t)t² · P₂ + t³ · P₃

🎨 输出效果

1. 二阶曲线(抛物线)

二阶Bezier曲线

特点

  • 3个控制点
  • 曲线形状类似抛物线
  • 中间控制点拉伸曲线

2. 三阶曲线(S型)

三阶Bezier曲线

特点

  • 4个控制点(最常用)
  • 可以形成 S 型或其他复杂形状
  • 起点和终点的切线由相邻控制点决定

3. 四阶曲线(波浪形)

四阶Bezier曲线

特点

  • 5个控制点
  • 可以表达更复杂的曲线形状
  • 中间控制点越多,曲线越灵活

4. 组合曲线(心形)

组合Bezier曲线

特点

  • 两条三阶曲线组合
  • 共享起点和终点
  • 展示了曲线的组合能力

🔧 核心代码

De Casteljau 递归实现

1
2
3
4
5
6
7
8
9
10
11
12
13
Vec2 deCasteljau(const std::vector<Vec2>& points, double t) {
std::vector<Vec2> temp = points;
int n = temp.size();

// 递归线性插值
for (int k = 1; k < n; k++) {
for (int i = 0; i < n - k; i++) {
temp[i] = temp[i] * (1 - t) + temp[i + 1] * t;
}
}

return temp[0];
}

曲线绘制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void drawBezier(const std::vector<Vec2>& controlPoints, 
unsigned char r, unsigned char g, unsigned char b,
int samples = 100) {
Vec2 prev = deCasteljau(controlPoints, 0);

// 均匀采样 t ∈ [0, 1]
for (int i = 1; i <= samples; i++) {
double t = (double)i / samples;
Vec2 curr = deCasteljau(controlPoints, t);
drawThickLine((int)prev.x, (int)prev.y,
(int)curr.x, (int)curr.y,
3, r, g, b);
prev = curr;
}
}

📊 技术细节

1. 算法复杂度

  • 时间复杂度: O(n²),n 是控制点数量
  • 空间复杂度: O(n)
  • 采样点数: 100-200(足够平滑)

2. 渲染技术

  • Bresenham 画线算法: 快速像素级画线
  • 粗线绘制: 多次偏移模拟抗锯齿
  • 控制点可视化: 红色圆点标记控制点

3. 数值稳定性

  • De Casteljau 算法数值稳定性优于直接展开公式
  • 适合高阶曲线(5阶以上)

💡 应用场景

  1. 字体设计: TrueType/OpenType 字体用三阶Bezier
  2. 矢量图形: SVG 路径、Illustrator/Figma
  3. 动画路径: CSS animations, SVG SMIL
  4. CAD/CAM: 工业设计中的曲线建模
  5. 游戏开发: 角色移动路径、相机轨迹

🚀 性能与优化

编译与运行

1
2
g++ -std=c++17 -O2 bezier.cpp -o bezier
./bezier

性能指标

  • 编译时间: <2秒
  • 运行时间: <1秒
  • 代码行数: 约180行
  • 输出文件: 4张PNG(17-19KB 每张)

📚 扩展方向

  1. B-spline 曲线: 局部控制性更好
  2. NURBS 曲线: 非均匀有理B样条
  3. 实时编辑器: 鼠标拖拽控制点
  4. 3D Bezier 曲面: 扩展到三维空间
  5. 自适应采样: 根据曲率调整采样密度

🎯 学习收获

  1. ✅ 理解了 De Casteljau 递归算法的几何意义
  2. ✅ 掌握了参数曲线的采样与绘制
  3. ✅ 实现了控制点、控制多边形的可视化
  4. ✅ 体验了从数学公式到视觉效果的转换

🔗 项目链接


项目日期: 2026-02-22
开发时间: 约1小时
技术栈: C++17, STB Image Write
难度: ⭐⭐⭐ (中等)