求导是参数曲线非常最重要的功能之一。比如切线计算、曲线拟合等等。本节的主要目的是介绍B样条曲线求导的方法。(ps:因为内容里含有矩阵,如果没有正确显示请刷新一下)。
B样条基函数的导数是:$$\frac{d}{du}N_{i,p}(u)=N_{i,p}^\prime (u)=\frac{p}{u_{i+p}-u_i}N_{i,p-1}-\frac{p}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}$$这个公式应该是从de-Boor递推推导而来的,我直接引用的Dr.shene的讲义,他同样没有给出详细推导过程。这个推导好处就是将p阶基函数的导数用p-1阶基函数的方式表现出来,去掉了低阶基函数上的导数符号。用B样条的矩阵形式表达B样条的导数:$$ C^\prime (u)= \begin{bmatrix} N_0&N_1&…&N_n&N_{n+1} \end{bmatrix}\begin{bmatrix}a_0P_0 \\ a_1P_1 \\ … \\ a_nP_n \\ 0\end{bmatrix} + \begin{bmatrix} N_0&N_1&…&N_n&N_{n+1} \end{bmatrix}\begin{bmatrix}0 \\ -a_1P_0 \\ … \\ -a_{n}P_{n-1} \\ -a_{n+1}P_n\end{bmatrix} \\ =\begin{bmatrix} N_0&N_1&…&N_n&N_{n+1} \end{bmatrix}\begin{bmatrix}a_0P_0 \\ a_1(P_1-P_0) \\ … \\a_n(p_n-p_{n-1}) \\ -a_{n+1}P_n \end{bmatrix} $$
其中 \(a_i = \frac{p}{u_{i+p}-u_i}\)。而且,为了表达简便,将\(N_{i,p-1}\)简写为\(N_i\)。需要注意的是,对于最常用的“clamped B Spline”,\(a_0=a_{n+1}=\frac{p}{0}\),根据Dr.shene给出的结论,显然这两项被当做0处理了。因此B样条的导数的最终形式是:$$C^\prime (u)=\begin{bmatrix}N_1,…,N_n\end{bmatrix}\begin{bmatrix} a_1(P_1-P_0) \\ … \\a_n(p_n-p_{n-1}) \end{bmatrix}$$$$a_i = \frac{p}{u_{i+p}-u_i}$$
这说明p阶“Clamped”B样条的导数是p-1阶B样条,而且导数的控制点个数比B样条少一个,节点个数比B样条少2个,分别去掉了原节点序列的首尾节点,所以导数曲线也是“clamped”B样条。
例如,3阶B样条的节点序列是\(\{0,0,0,0,…,t,t,t,t\}\)那么其导数曲线的节点序列就是\(\{0,0,0,…,t,t,t\}\)。
欲求曲线在参数u处的导数,只需要计算出B样条导数样条曲线的控制点序列,然后应用de Boor算法求导数曲线的值就可以了。所以说样条曲线的求导十分方便。
再来看“clamped”B样条首尾点切线的情况。通过将首尾节点的重复度变为p+1,我们已经获得了与Bezier曲线一样良好的性质:首尾点分别与首尾控制点相同。而首尾点的切向量,正是\(a_1(P_1-P_0)\)与\(a_n(P_n-P_{n-1})\),说明B样条首尾处的且向量与控制多边形的首末相切,也与Bezier的性质一样。
所以说,从应用的角度讲,因为利于使用,方便实现,“clamped”B样条的使用场景大大超过了非“clamped”情况。因此,我后面有关B-Spline话题,都会着重讲到“clamped”B样条。