从本篇开始,我将陆续介绍NURBS(Non-Uniform Relational B-Spline 非均匀有理B样条)有关的算法以及实现。作为背景,我们有必要了解参数曲线的知识。
参数曲线的形式
我们在提到数学函数时,最先想到的是\(y=f(x)\),\(z=f(x,y)\)或者更一般的\(f(x,y,z,…)=0\)的形式。但是这种形式并不便于计算机编程实现。使用参数曲线形式更好。参数曲线是将曲线(方程)f 以 \(x=f_x (t) ,y=f_y(t)\)的形式来表达。比如直线:$$\begin{equation}\left\{\begin{aligned}
\overset{.}
x &=x_0+v_x t\\
y&=y_0 + v_y t\\
z&=z_0 + v_z t\\
\end{aligned}
\right.
\end{equation}$$
圆:$$\begin{equation}\left\{\begin{aligned}
\overset{.}
x &=a + cos(\theta)r\\
y&=b + sin(\theta)r\\
\end{aligned}
\right.
\end{equation}$$
参数曲线建立了\(t\rightarrow (x,y,z)\)的映射,即对应定义域内任意一点t,均有空间位置\((x,y,z)\)与之对应。参数的取值,有时候具有其物理意义。比如常见的以时间t为参数表达的里程与时间的关系曲线。NURBS曲线就是以参数曲线的形式定义的。
正切向量与切线
在参数曲线上对应参数t处的正切向量,为各个维度对t求导后的数字构成的向量,如果参数曲线形式为 \(F(t)=(f(t),h(t),g(t))\),那么其正切向量可以表达为 \(F'(t)=[f'(t),h'(t),g'(t)]^T\)。通常,这样求出正切向量的模长不唯一,需要将其归一化。
参数曲线在t处的切线为 \(l = [f(t),h(t),g(t)]^T + [f'(t),h'(t),g'(t)]^Tu\)。我给出的切线的定义也是参数曲线。
曲率
曲率是曲率半径的倒数,是用来描述曲线在某点处弯曲程度的指标。从高中课本上,我们已经知道\(y=f(x)\)的曲率为:$$\kappa =\frac{|y”|}{(1+y’^2)^{3/2}}$$参数曲线的曲率是这样的:$$\kappa = \frac{|f'(t)\times f”(t)|}{|f'(t)^3|}$$
我们可以证明一下\(y=f(x)\)的曲率只是参数曲线曲率的特殊形式。\(y=f(x)\)可以用 \(y=f(t),x=t\)来表示,那么 \(F'(t) = [f'(x),1]^T,F”(t)=[f”(x),0]\)。$$\kappa = \frac{|f'(x)\times 0 – f”(x)\times 1|}{|1*1+f'(x)^2|^{3/2}} = \frac{|y”|}{(1+y’^2)^{3/2}}$$
所以,以后大家直接记住参数曲线的求导公式就好了。
连续性
对于两段连续的曲线,考虑从一个曲线过渡到另一个曲线的“平滑”程度,成为参数曲线的连续性问题。很多业务都对曲线提出了连续性要求。如公路设计。假设你在公路上行驶,当从一段公路行驶到另一段公路时,如果连接处几何坐标相同(当然,否则你就掉沟里去了),那么我们称参数曲线\(C^0\)连续。如果在切换时速度大小方向不变(即切向量不变),那么称之为\(C^1\)连续。如果加速度没有变化,则成为\(C^2\)连续,以此类推。就是说,如果两个曲线能够保证0到k阶的导数向量均相等,那么称之为\(C^k\)连续。如果曲率没有发生变化,则称为曲率连续。注意,如果\(C^2\)连续,那么曲率一定连续,如果曲率连续,不一定\(C^2\)连续。曲率是一个标量。
特别需要提到的是,参数的选取与连续性有直接关系。还以公里行驶为例,如果以时间t为参数表示里程,那么切向量就是速度v。如果在一段路上,你的速度表是以 公里/小时记录的,另一段路上,你的速度计改为 mile/h。即使你实际上并没有改变车速,但是因为两段路参数化方式的不一样,仍然达不到\(C^1\)连续。
因此,我们采用“Geometric Continuity”,几何连续来表达这样的连续问题,即如果存在两种参数化方式,能够使得两个参数曲线\(C^k\)连续,那么则认为两个曲线\(G^k\)连续。对于我们常用的\(G^1,G^2\),可以用更特定的方式描述:
- 两个\(C^0\)曲线当且仅当在连接处一阶导数方向相同时(注意,不能是相反,即两个切向量点积大于0)\(G^1\)连续。
- 两个\(C^1\)曲线当且仅当在连接处的 二阶导数差值\(f”(u)-g”(u)\)与一阶导数平行时\(G^2\)连续。
在一些商业软件中,有对应的实现。我原来做地图时用到的coreldraw ,即有非常方便的连接工具,使得bezier曲线连接时保证方向不发生变化。
本文参考了 Dr. Ching-Kuang Shene 的 Introduction to Computing with Geometry 课程,非常棒的材料,看到浙大CAD实验室的有关nurbs的教程也参考了。推荐阅读。
小车车速不同的例子非常好,感谢博主的文章,醍醐灌顶
很好的文章,感谢博主