上一篇记录了Cube Spline的原理及求解过程,这里记录一下Kochanek-Bartels Cubic Splines(TCB Spline)的原理及推导。TCB Spline是D. Kochanek, R. Bartels于1984年提出的一种样条插值方法,提供三个参数:T(张量参数), C(连续性参数), B(偏移参数),使调整曲线形状更加灵活。
一、基本概念
\(n\)个关键样本记为:
\[\{ (s_k, \boldsymbol P_k, \boldsymbol T_k^i, \boldsymbol T_k^o) \}_{k=0}^{n-1} \]
其中\(s_k\)表示采样时间(即采样间隔),\(\boldsymbol P_k\)表示样本坐标位置, \(\boldsymbol T_k^i\) 和 \(\boldsymbol T_k^o\)分别表示当前样本输入和输出切线向量。如下图所示

从\(P_{k-1}\)至\(P_k\),接近\(P_k\)处的切线方向作为\(T_K^i\),从\(P_k\)至\(P_{k+1}\),离开\(P_k\)处的切线作为\(T_K^o\)
二、参数说明
切线是依据相邻点及T, C,B三个参数控制,默认值都为0,即Catmull-Rom Spline,$$T_k^i = T_k^o = \frac{1}{2}((\boldsymbol P_{k+1} - \boldsymbol P_k) +(\boldsymbol P_k - \boldsymbol P_{k-1})) = \frac{\boldsymbol P_{k+1} - \boldsymbol P_{k-1}}{2}$$
下图是Catmull-Rom Spline在\((0,(14, 256)), (1,(14, 86)), (2,(142, 86)), (3,(142, 256)), (4,(270, 256)), (5,(270, 86))\) 样本处的样条形状

1. T作为张量参数
记为\(\tau_k \in [-1, 1]\),控制曲线在控制点处的弯曲程度
\[T_k^i = T_k^o = \frac{1-\tau_k}{2}((\boldsymbol P_{k+1} - \boldsymbol P_k) +(\boldsymbol P_k - \boldsymbol P_{k-1})) \]

值越接近于1,曲线在控制点处越紧密,值越接近-1,曲线在控制点处越松弛。
2. C作为连续性参数
记为\(\gamma_k \in [-1, 1]\),控制曲线在控制点处的连续性
\[T_k^i = \frac{1+\gamma_k}{2}(\boldsymbol P_{k+1} - \boldsymbol P_k) +\frac{1-\gamma_k}{2}(\boldsymbol P_k - \boldsymbol P_{k-1})) \\ T_k^o = \frac{1-\gamma_k}{2}(\boldsymbol P_{k+1} - \boldsymbol P_k) +\frac{1-\gamma_k}{2}(\boldsymbol P_k - \boldsymbol P_{k-1})) \]

随着\(|\gamma_k|\)接近于1,控制点形成角点越明显,其方向由\(\gamma_k\)的符号决定。
3. B作为偏移参数
记为\(\beta_k \in [-1, 1]\),通过单侧导数加权控制曲线在控制点处的路径方向
\[T_k^i = T_k^o = \frac{1-\beta_k}{2}(\boldsymbol P_{k+1} - \boldsymbol P_k) +\frac{1+\beta_k}{2}(\boldsymbol P_k - \boldsymbol P_{k-1}) \]

\(\beta_k\)越接近于-1,外切线控制曲线通过控制点的路径方向,越接近于1,内切线控制曲线通过控制点的路径方向。
4. 合并三个参数
三个参数合并后其对\(T_K^i\)和\(T_K^o\)的影响如下:
\[T_k^i = \frac{(1-\tau_k)(1+\gamma_k)(1-\beta_k)}{2}(\boldsymbol P_{k+1} - \boldsymbol P_k) +\frac{(1-\tau_k)(1-\gamma_k)(1+\beta_k)}{2}(\boldsymbol P_k - \boldsymbol P_{k-1})) \\ T_k^o = \frac{(1-\tau_k)(1-\gamma_k)(1-\beta_k)}{2}(\boldsymbol P_{k+1} - \boldsymbol P_k) +\frac{(1-\tau_k)(1+\gamma_k)(1+\beta_k)}{2}(\boldsymbol P_k - \boldsymbol P_{k-1})) \]
三、方程推导
1. 目标方程
类似上一篇cube spline---三次样条插值,在子区间\([s_k, s_{k+1}]\)上,即从样本 \((s_k, \boldsymbol P_k, \boldsymbol T_k^i, \boldsymbol T_k^o)\) 到 \((s_{k+1}, \boldsymbol P_{k+1}, \boldsymbol T_{k+1}^i, \boldsymbol T_{k+1}^o)\) 三次样条曲线可以表示成
\[\boldsymbol X_k(s) = \boldsymbol A_k + (\frac{s-s_k}{\boldsymbol \Delta_k})\boldsymbol B_k + (\frac{s-s_k}{\boldsymbol \Delta_k})^2 \boldsymbol C_k + (\frac{s-s_k}{\boldsymbol \Delta_k})^3 \boldsymbol D_k \]
其中\(\boldsymbol \Delta_k = s_{k+1} - s_k\),即两个样本之间的距离,\(s \in [s_k, s_{k+1}]\)。
其一阶导为:
\[\boldsymbol X_k^{'}(s) = \frac{1}{\boldsymbol \Delta_k} ( (\boldsymbol B_k + 2(\frac{s-s_k}{\boldsymbol \Delta_k}) \boldsymbol C_k + 3(\frac{s-s_k}{\boldsymbol \Delta_k})^2 \boldsymbol D_k) \]
二阶导为:
\[\boldsymbol X_k^{''}(s) = \frac{1}{\boldsymbol \Delta_k^2} ( 2\boldsymbol C_k + 6(\frac{s-s_k}{\boldsymbol \Delta_k}) \boldsymbol D_k) \]
三阶导为:
\[\boldsymbol X_k^{'''}(s) = \frac{1}{\boldsymbol \Delta_k^3} ( 6 \boldsymbol D_k) \]
假设有\(n\)个子区间,则每个子区间存在\(\boldsymbol A_k \boldsymbol B_k \boldsymbol C_k \boldsymbol D_k\)四个参数共\(4n\)个参数需要求解。
2. 已知条件
插值条件
子区间左端点及右端点在当前曲线上,即有$$\boldsymbol X_k(s_k) = \boldsymbol P_k ,\ \boldsymbol X_k(s_{k+1}) = \boldsymbol P_{k+1}$$
这里一共有\(2n\)个方程。
插值条件
子区间左端点处的一阶导可作为\(\boldsymbol T_k^o\),右端点处的一阶导可作为\(\boldsymbol T_{k+1}^i\)即:
\[\boldsymbol X_k^{'}(s_k) = \boldsymbol T_k^o \\ \boldsymbol X_k^{'}(s_{k+1}) = \boldsymbol T_{k+1}^i \]
这里一共也有\(2n\)个方程。
3. 方程推导
由第2步中已知条件可知:
\[ \begin{align} &\boldsymbol A_k = \boldsymbol P_k \nonumber\\ &\boldsymbol A_k + \boldsymbol B_k + \boldsymbol C_k + \boldsymbol D_k = \boldsymbol P_{k+1} \nonumber\\ &\boldsymbol B_k = \boldsymbol \delta_k T_k^o \nonumber\\ &\boldsymbol B_k + 2 \boldsymbol C_k + 3\boldsymbol D_k = \boldsymbol \delta_k T_{k+1}^i \nonumber\\ \end{align} \]
可推导出:
\[ \begin{align} \boldsymbol A_k &= \boldsymbol P_k \nonumber\\ \boldsymbol B_k &= \boldsymbol \delta_k T_k^o \nonumber\\ \boldsymbol C_k &= 3(\boldsymbol P_{k+1} - \boldsymbol P_k) - \delta_k (2 \boldsymbol T_k^o + \boldsymbol T_{k+1}^i) \nonumber\\ \boldsymbol D_k &= -2(\boldsymbol P_{k+1} - \boldsymbol P_k) + \boldsymbol \delta_k ( \boldsymbol T_k^o + \boldsymbol T_{k+1}^i)\nonumber\\ \end{align} \]
4. 边界条件
由3中式子可得到每个子区间四个参数\(\boldsymbol A_k \boldsymbol B_k \boldsymbol C_k \boldsymbol D_k\),但在计算第一个样本点的切线时,其左边没有节点,同样计算最后一个样本时,其右边也没有节点,所以这里需要单独给出\(\boldsymbol T_0^o\)和\(\boldsymbol T_{n-1}^i\)的计算公式
\[\boldsymbol T_0^o = \frac{(1-\tau_0)(1-\gamma_0)(1-\beta_0)}{2}(\frac{\boldsymbol P_1 - \boldsymbol P_0}{\Delta_0}) \]
\[\boldsymbol T_{n-1}^i = \frac{(1-\tau_{n-1})(1-\gamma_{n-1})(1+\beta_{n-1})}{2}(\frac{\boldsymbol P_{n-1} - \boldsymbol P_{n-2}}{\Delta_{n-2}}) \]
四、代码实现
参考:6.Implementation
参考链接
Kochanek-Bartels Cubic Splines (TCB Splines)