曲线(Curves)

三维中摄像机的运动、动画软件要完成的物体的运动、矢量字体的控制点 ......

曲线(Curves)

这就是下面要说的贝塞尔曲线(Bézier Curves) 曲线(Curves)

用一系列控制点去定义某段曲线,上图就是用 p0、p1、p2、p3 这四个点定义的贝塞尔曲线。而且这里还有个系数 3,后面就会明白。

通过这四个点我可以定义这条曲线它的起始点和终止点一定在 p0 和 p3 上,并且这条线的起始切线和结束切线一定都是 p0p1 方向和 p2p3 方向。控制点并不一定要经过它。

 

de Casteljau Algorithm 对于三个点 b0、b1、b2
曲线(Curves)

假设我有一个从 0 到 1 的时间轴,点 b0 就是时间 0 的位置,点 b2 就是时间 1 的位置。

如果我想画出这条曲线,就是要补齐从 0 到 1 的所有点的位置。那我们看时间 t 曲线的点在哪里。

曲线(Curves)

两边都按如图所示找到边上的点的位置

曲线(Curves)

连线后再找一个点,那个点就处于曲线之上。

曲线(Curves)

同样的办法将所有点补齐就得到了这条贝塞尔曲线:

曲线(Curves)

为什么这种方法是显式表示呢?因为显式表示可以用参数来定义,这里的 t 就是参数的表示。

四个点定义的贝塞尔曲线,每一条边上找点,很显然这是一个递归的算法。

曲线(Curves)

那么在代数上如何表示呢?即时间 t 它的点在哪。

曲线(Curves)

示例:三个控制点得到的方程。是点 b0、点 b1、点 b2 的一个组合,很符合最早的分析。

曲线(Curves)

(1 - t + t)2 的展开,而再加一个点,就是系数是 1 3 3 1 的形式。所以这其实就是 (s + t)n 的展开式

曲线(Curves)

伯恩斯坦多项式,描述二项分布的一个多项式。表示任意一项是多少。

简化一下,任意阶数的贝塞尔曲线在任意时刻 t 上的点的位置,就是由伯恩斯坦多项式作为系数对给定控制点的加权。

贝塞尔曲线也不一定限制在平面内,在空间中我也同样可以得到贝塞尔曲线:

曲线(Curves)

 

伯恩斯坦多项式

曲线(Curves)

贝塞尔曲线规定了很多不错的性质,如曲线必须过起点和终点,并且起始和终止切线的方向一定是 3 倍的 b1 - b0 和 b3 - b2(以四个控制点为例,其它的并不一定是 3),仿射变换不变性,曲线一定在控制点的凸包内。

曲线(Curves)

凸包:能够包围一系列给定的几何形体的最小的凸多边形。就像一块木板钉上很多钉子,你用一个橡皮筋能够框住的最大形状叫做凸包。

比如一系列控制点在一条直线上,要画出它的贝塞尔曲线,那这条曲线一定是画在这条直线上,因为凸包的限制。你会知道贝塞尔曲线绝对不会超过给定的控制点形成的凸包的范围内。

曲线(Curves)

麻烦的在于控制点一多起来就不太好控制。

曲线(Curves)

于是人们就想,为什么我要用这么多控制点来定义一个贝塞尔曲线呢?我能不能用很少的控制点来定义一段贝塞尔曲线。把这些贝塞尔曲线连起来。于是人们就发明了逐段地定义贝塞尔曲线,或者说每四个控制点来定义每段贝塞尔曲线。

曲线(Curves)

这种定义方法就得到了非常广泛的应用。也正是 Photoshop 里的钢笔工具。

那么如何保证每段贝塞尔曲线的连接处是光滑的呢?

根据之前公式的定义,曲线起点终点的切线的导数要相等,连接处的控制点共线且等长。如果不等长也不能算光滑,因为切线不仅要方向一样,大小也要一样。

曲线(Curves)

拿两段贝塞尔曲线说明连续性:

曲线(Curves)

只保证有连接,这种连续叫 C0 连续

曲线(Curves)

像刚刚那样,切线也能够连续,就叫 C1 连续,可以理解成一阶导数的连续

曲线(Curves)

更高阶的连续也有,我们叫曲率连续。一阶连续看上去已经挺好的了,有时在制造上我们仍然觉得不够,会采用 C2 连续。

贝塞尔曲线当然不只是图形学上应用的曲线,还有各种各样别的曲线。

曲线(Curves)

( B 样条极其复杂,可能是图形学里最复杂的一块,NURBS 是 B 样条更延申的一步)

曲线(Curves)

 

贝塞尔曲面

曲线(Curves)

4 * 4 个控制点得到的贝塞尔曲面:

其实还是先从水平方向做一下贝塞尔曲线,再从垂直方向上做一下贝塞尔曲线,最后得到的贝塞尔曲面。

当然也要考虑曲面之间如何做到严丝合缝平滑的问题。

曲线(Curves)

原先用一个时间 t 表示,现在在二维的方向上要用 (u, v) 来进行控制。

曲线(Curves)

找到曲面在 (u, v) 参数下的位置

曲线(Curves)

曲线(Curves)

 

 

 

 

 

 

 

 

 

 

 

 

上一篇:数据类型的转换


下一篇:Git 状态 untracked 和 not staged的区别