在圖形學、CAD、數據可視化等領域,如何用有限離散點構造光滑曲線是核心課題。本文深度解析三種經典插值算法——二次拋物線法、二次 B樣條法、三次參數樣條法——並提供可直接移植的 C++ 參考實現,助你根據精度與性能需求選型。
| 算法 | 連續性 | 局部控制 | 計算量 | 適用場景 |
|---|---|---|---|---|
| 二次拋物線 | C¹ 連續 | 全局影響 | 低 | 簡單繪圖、教學演示 |
| 二次 B樣條 | C¹ 連續 | 局部支持(3 點) | 低 | 交互式曲線編輯 |
| 三次參數樣條 | C² 連續 | 全局/局部可選 | 中 | 高精度工程繪圖 |
原理:以四個鄰近控制點構造一段三次參數曲線,通過端點處的虛擬點複製(p[0]=p[1], p[n+1]=p[n])處理邊界。參數 t ∈ [0, 0.5],步長 0.5/k,每段插入 k-1 個點。
基函數:
a = 4t² - t - 4t³
b = 1 - 10t² + 12t³
c = t + 8t² - 12t³
d = 4t³ - 2t²
關鍵代碼片段:
void paowuxian(int *x, int *y, int n, unsigned int k) {
// 邊界虛擬點
*x = *(x+1); *y = *(y+1);
*(x+n+1) = *(x+n); *(y+n+1) = *(y+n);
float t = 0.5f / k;
moveto(*(x+1), *(y+1));
for (int i = 0; i < n-1; ++i) {
for (int j = 1; j < k; ++j) {
float t1 = j * t, t2 = t1*t1, t3 = t2*t1;
float a = 4*t2 - t1 - 4*t3;
float b = 1 - 10*t2 + 12*t3;
float c = t1 + 8*t2 - 12*t3;
float d = 4*t3 - 2*t2;
float tx = a*x[i] + b*x[i+1] + c*x[i+2] + d*x[i+3];
float ty = a*y[i] + b*y[i+1] + c*y[i+2] + d*y[i+3];
lineto(tx, ty);
}
}
lineto(*(x+n), *(y+n)); // 收尾
}
原理:均勻二次 B樣條,每段由三個控制點決定,具備局部修改特性。曲線不經過控制點,但逼近控制多邊形。起點取前兩點中點,參數 t ∈ [0, 1],步長 1/k。
基函數:
a = (t² - 2t + 1) / 2
b = t - t² + 0.5
c = t² / 2
關鍵代碼片段:
void byangtiao(int *x, int *y, int n, unsigned int k) {
*x = *(x+1); *y = *(y+1);
*(x+n+1) = *(x+n); *(y+n+1) = *(y+n);
float t = 1.0f / k;
moveto((x[0]+x[1])/2.0f, (y[0]+y[1])/2.0f);
for (int i = 0; i < n; ++i) {
for (int j = 1; j < k; ++j) {
float t1 = j * t, t2 = t1*t1;
float a = (t2 - 2*t1 + 1) * 0.5f;
float b = t1 - t2 + 0.5f;
float c = t2 * 0.5f;
float tx = a*x[i] + b*x[i+1] + c*x[i+2];
float ty = a*y[i] + b*y[i+1] + c*y[i+2];
lineto(tx, ty);
}
}
}
原理:作者註釋「好像叫三次參數樣條法」,實為三次 Cardinal Spline / Catmull-Rom 變體。同樣使用四點支撐,但參數域 t ∈ [0, 0.5],基函數與二次拋物線法完全一致,僅數據結構改為 int p[][2] 並額外增加 D 偏移量(可能用於多曲線疊加)。
關鍵差異:
p[n+2][2],便於向量化運算moveto(p[1][0], p[1][1]+D) 引入垂直偏移lineto(x, y, 15) 攜帶顏色/屬性參數float 足夠屏幕繪圖;科學計算建議升級 double 並引入 Eigen / GLM 矩陣庫。CurveFitter 抽象基類,派生 QuadraticParabolic、QuadraticBSpline、CubicParametricSpline,配合 std::vector<Point2f> 與範基 for 循環,消除裸指針與手動索引。掌握這三種算法的數學本質與代碼結構,你就能在「精度、速度、局部控制」三角權衡中做出最佳選擇,並輕鬆擴展至 NURBS、Subdivision 等高階曲線表示。