B样条插值是通过反解控制点使曲线精确经过给定数据点,需解线性方程组;而普通B样条仅由控制点和节点定义分段多项式曲线,不保证过控制点。

什么是B样条插值,和普通样条有什么区别
B样条插值不是直接让曲线穿过所有控制点(那是插值型B样条的常见误解),而是通过一组控制点 control_points 和节点向量 knots 定义一条分段多项式曲线,它不一定经过控制点;若要实现“插值”,即让曲线精确经过给定数据点 data_points,必须反解控制点——这叫插值型B样条拟合,本质是解线性方程组。
关键判断:标准 std::vector + 手写 De Boor 算法只能做求值(evaluating),不能自动插值。你要的是“给定 P₀…Pₙ,构造一条 B 样条使其满足 C(tᵢ) = Pᵢ”,这就绕不开矩阵求解。
如何构造插值型B样条:节点、次数、参数化三要素缺一不可
插值成败高度依赖三个输入是否合理:
-
degree:通常取 3(三次B样条),太低(如 1)欠光滑,太高(≥5)易振荡且病态 -
parameterization:不能用等距tᵢ = i,推荐 chord length(弦长参数化):t[0] = 0,t[i] = t[i-1] + distance(data_points[i], data_points[i-1]) -
knots:需满足插值条件数量匹配。对n+1个数据点、次数p,需n+1个控制点 → 节点数应为(n+1) + p + 1;常用开节点(open uniform):前p+1个为 0,后p+1个为 1,中间均匀分布
常见错误现象:matrix is singular 或插值结果严重偏离——八成是节点向量没按开形式构造,或参数 tᵢ 重复导致基函数矩阵列线性相关。
用Eigen解控制点:核心是构造基函数矩阵 A
对每个数据点 i,计算其参数 tᵢ 处所有非零基函数值 N_{j,p}(tᵢ),填入矩阵 A[i][j](j 是控制点索引)。最终解 A × X = P,其中 X 是待求控制点坐标(x/y/z 分开解)。
i
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











