此为个人学习笔记,总结内容来源于网络各个平台,如有错误欢迎指摘
几何表示
曲线与曲面
本节附加资料:
- Making things with Maths (acko.net)
- 游戏开发技术杂谈2:理解插值函数lerp - 知乎 (zhihu.com)
- (57条消息) 贝塞尔曲线简单介绍_xiaozhang2019的博客-CSDN博客_贝塞尔曲线
贝塞尔曲线 Bezier Curves
在很多地方你都会见到这种通过控制点控制描绘出的曲线,这就是贝塞尔曲线
关于历史
为什么贝塞尔曲线要用德卡斯特利奥算法计算?伯恩斯坦多项式又是怎么掺和进来的?
用一句话概括这段历史就是:经过一系列的数学证明后,对于一个连续函数,你可以将它写成若干个伯恩斯坦多项式相加的形式,而就职于雪铁龙的德卡斯特利奥在1959年根据他设计的算法图形化了伯恩斯坦多项式,但就职于雷诺的贝塞尔在1962年将这种曲线用于汽车设计中,将其发扬光大,因此被称为了贝塞尔曲线
更多内容请在附加资料中查阅
lerp函数
课程中对这部分的讲解将参数t作为了时间的尺度,而这里将根据lerp函数的定义做出解释,此处内容来源自本节参考资料
lerp函数在上一章的着色一节的线性插值小节中就已经出现了,现在让我们看一下它的定义:
l
e
r
p
(
y
1
,
y
2
,
w
e
i
g
h
t
)
=
y
1
+
(
y
2
−
y
1
)
∗
w
e
i
g
h
t
lerp(y_1,y_2,weight) = y_1 + (y_2 - y_1) * weight
lerp(y1,y2,weight)=y1+(y2−y1)∗weight
这里的
y
1
y_1
y1被称为起点,而
y
2
y_2
y2被称为终点,weight作为一个权重被限制在0到1的取值范围中,lerp函数就是取值
y
1
y_1
y1到y2中间的一个值
取多少呢?就由weight来控制,当weight为0.5时,它正好落在起点和终点的中间
公式还可改写为:
l
e
r
p
(
y
1
,
y
2
,
w
e
i
g
h
t
)
=
(
1
−
w
e
i
g
h
t
)
∗
y
1
+
w
e
i
g
h
t
∗
y
2
lerp(y_1,y_2,weight) = (1 - weight) * y_1 + weight * y_2
lerp(y1,y2,weight)=(1−weight)∗y1+weight∗y2
简单来说,lerp函数就是在
y
1
y_1
y1和
y
2
y_2
y2之间过渡,唯一不同的地方就是,
y
1
y_1
y1和
y
2
y_2
y2可以是一个值,也可以是一个函数。比如,我们可以在正弦函数和线性函数之前做过渡,我们先看一下正弦函数
y
=
sin
x
y = \sin x
y=sinx
再看一下最简单的线性函数 y = x y = x y=x
在它俩之间做过渡,我们只需要写出lerp(sin(x),x,0.5)即可。当然,可以调整weight参数观察不同的结果。
weight = 0.5:
weight = 0.8:
weight = 0.2:
lerp函数的两种不同作用为:
- 构造新的函数
- 在两个值之间进行过渡
这也就是为什么在插值的时候经常使用lerp函数的原因
德卡斯特利奥算法 De Casteljau’s Algorithm
定义一个图中这样的lerp函数:在两点ab之间定义一点p,使得AP与PB的比例为1-t比t,为什么前半部分是1-t呢?请回顾lerp函数的定义
而当一共存在三个端点时,我们分别两两做出它们的点p,再将这两个p点作为端点,做出最后的一个点p,这个点描绘出的轨迹就是贝塞尔曲线,由三个控制点画出的贝塞尔曲线是二阶贝塞尔曲线 Quadratic Bezier Curve
在此之中我们一共使用了三次lerp函数,请注意这些t是共享的,是一个全局变量
这部分是一个动画内容,但我没办法将gif格式的文件放在这里,十分推荐前往本节参考资料中观看一次,贝塞尔曲线内容在演示的后面
在课上我们将t作为一个时间量,它是满足全局变量的性质的,通过图中上标为0的字母经过一次lerp后得到上标为1的端点,之后利用这些端点得到上标为2的点,这些步骤随着全局变量时间t的变化而描绘出的最高阶点的轨迹就是贝塞尔曲线
当控制点来到4个的时候,共需要进行6次lerp函数才能得到三阶贝塞尔曲线 Cubic Bezier Curve
我们一直在用向量表示端点,而如果将二维向量变为三维向量,那么我们就得到了一条在空间中的贝塞尔曲线,这部分的更多内容将在后面讲解
讲了这么多似乎还没有出现过德卡斯特利奥算法对吧,通过对三个点、四个点贝塞尔曲线绘制距离,很明显能够看出对于n阶贝塞尔曲线而言,需要调用n + (n - 1) + (n - 2) + … + 1 = n(1 + n) / 2次lerp函数
越高阶的贝塞尔曲线就需要越多的调用次数,也会产生非常多的中间点,以一个三阶贝塞尔曲线为例,图中给出了起始的4个点 b x b_x bx以及第一层lerp函数产生的 b x 1 b_x^1 bx1、二层lerp函数产生的 b x 2 b_x^2 bx2、三层lerp函数产生的 b x 3 b_x^3 bx3
在二阶贝塞尔曲线中,将 b 0 2 b_0^2 b02用 b x b_x bx表示后可发现每一项的系数为 t t t和 1 − t 1-t 1−t的组合,更像是 [ ( 1 − t ) + t ] 2 [(1 - t) + t]^2 [(1−t)+t]2的展开式
事实上这个规律是满足德卡斯特利奥算法的,即图中的
b
n
(
t
)
=
b
0
n
(
t
)
=
∑
j
=
0
n
b
j
B
j
n
(
t
)
b^n(t) = b_0^n(t) = \sum_{j = 0}^{n} b_j B_j^n(t)
bn(t)=b0n(t)=j=0∑nbjBjn(t)
图中对各部分含义都作出了说明:
- b n ( t ) b^n(t) bn(t):n阶贝塞尔曲线的绘制点,n次向量多项式
- b j b_j bj:贝塞尔曲线的控制点,n维空间中的向量
- B j n B_j^n Bjn:伯恩斯坦多项式,n次的标量多项式
伯恩斯坦多项式 Bernstein Polynomial
伯恩斯坦多项式已经给出:
B
i
n
(
t
)
=
(
n
i
)
t
i
(
1
−
t
)
n
−
i
,
i
=
0
,
1
,
2
,
.
.
.
,
n
B_i^n(t) = \left (\;\begin{array}{c} n \\ i \end{array} \;\right) t^i (1 - t)^{n - i},i=0,1,2,...,n
Bin(t)=(ni)ti(1−t)n−i,i=0,1,2,...,n
但换一种方式可能更容易理解:
B
i
n
(
t
)
=
C
n
i
t
i
(
1
−
t
)
n
−
i
,
i
=
0
,
1
,
2
,
.
.
.
,
n
B_i^n(t) = C_n^i t^i (1 - t)^{n - i},i=0,1,2,...,n
Bin(t)=Cniti(1−t)n−i,i=0,1,2,...,n
接下来看一个例子:
这是在三维空间中求一个三阶贝塞尔曲线的绘制点的情况
其中n=3,则分别有系数中的常数项 a 0 = C 3 0 = 1 a_0 = C_3^0 = 1 a0=C30=1、 a 1 = C 3 1 = 3 a_1 = C_3^1 = 3 a1=C31=3、 a 2 = C 3 2 = 3 a_2 = C_3^2 = 3 a2=C32=3、 a 3 = C 3 3 = 1 a_3 = C_3^3 = 1 a3=C33=1,非常数项系数可由公式得出
通过对t进行0到1的变化就可绘制出一条贝塞尔曲线
伯恩斯坦多项式本身还具有很多的性质,例如三阶的情况下从图中可以看出它的图形是对称的,事实上它的图形都是对称的,因为 C n i = C n n − i C_n^i = C_n^{n-i} Cni=Cnn−i,而剩下的参数也满足这种关系
而其它的性质诸如:
- 绘制点在t为0时一定在起点,为1时一定在终点
- 起点与终点的切线性质:图中给出了三次贝塞尔曲线情况下的性质,即起点的切线和终点的切线可由控制点与参数表示,对于其他次的贝塞尔曲线可根据伯恩斯坦多项式推导得出
- 对贝塞尔曲线进行仿射变换可由对控制点进行仿射变换代替,但其他操作不一定满足,例如投影
- 凸包性质,被绘制出的曲线一定在控制点构成的凸包内
凸包 Convex Hull
凸包:
- 是凸多边形
- 能把所有点都包围进去
分段贝塞尔曲线 Piecewise Bezier Curves
基本信息
虽然能确定贝塞尔曲线一定会在控制点的凸包之内,但对于高阶贝塞尔曲线很难去控制局部细节
在这样的一个十次贝塞尔曲线中,总共11个控制点来控制曲线的形状,牵一发而动全身
可以将高阶的贝塞尔曲线拆分成许多低阶的贝塞尔曲线的组合,而最常见的是用三阶贝塞尔曲线来拼接,它的四个控制点中的两个被隐藏起来了,即图中蓝色圆点部分
有一件事你可能会很疑惑:为什么图中有五个点,而你只标注了其中的四个,多出来的是什么?
其实它也可以是这样的
而多出来的东西是为了保证,或者说是让它满足一些特定的关系,即连续性
连续性 Continuity
如果你画过贝塞尔曲线,你就会注意到有些时候会出现很不平滑的部分,这分段贝塞尔曲线在拼接时发生的问题
而为了让得到的曲线变得平滑,指定了一系列的标准
例如在N次可数空间IR中有这样的的两段三次贝塞尔曲线
如果它们的首尾控制点只是简单相连而已,则满足 C 0 C^0 C0连续
如果它们的首尾控制点满足切线等长的话,则满足 C 1 C^1 C1连续
图中的公式直接使用了相邻控制点作为计算参数,这是贝塞尔曲线的性质,如果你忘记了可以去再看一遍
更高阶的连续不再介绍
样条线 Spline
此部分仅作了解
样条的英语单词spline来源于可变形的样条工具,那是一种在造船和工程制图时用来画出光滑形状的工具
一种可控的曲线
B样条 B-Splines
由伯恩斯坦多项式作为基函数的样条
贝塞尔曲线的一种扩展、一般化的形势,具有局部性,修改其中的一个控制点影响范围可控
非均匀有理B样条 NURBS
是B样条的扩展,引入了权重
NURBS就是专门做曲面物体的一种造型方法
NURBS造型总是由曲线和曲面来定义的,所以要在NURBS表面里生成一条有棱角的边是很困难的
就是因为这一特点,我们可以用它做出各种复杂的曲面造型和表现特殊的效果,如人的皮肤,面貌或流线型的跑车等
贝塞尔曲面 Bezier Surface
贝塞尔曲线的绘制过程是点动成线,而贝塞尔曲面就是点动成线、线动成面
要得到这样的一个曲面,我们需要什么?
将一个在二维空间中的4*4的点阵
引入到三维空间中,并重新排布这十六个控制点
将每四个点形成的贝塞尔曲线,共计四条贝塞尔曲线,再连接它们的四个绘制点组成一条新的曲线
将它们的这些点随意调整就可得到许许多多的形状
它的构造过程类似于双线性插值,由第一次构成的贝塞尔曲线,再构造出一条新的曲线,从而绘制出整个曲面
在这样的曲面上映射纹理坐标时,u与v分别对应了第一次贝塞尔曲线绘制与第二次贝塞尔曲线绘制时的参数t,且两者正好范围相同
贝塞尔曲面也可类似分段,而如何将这些曲面严丝合缝地拼接起来,此处不作讨论
更多的…
664499748427)]
它的构造过程类似于双线性插值,由第一次构成的贝塞尔曲线,再构造出一条新的曲线,从而绘制出整个曲面
[外链图片转存中…(img-yA3fgeVy-1664499748427)]
在这样的曲面上映射纹理坐标时,u与v分别对应了第一次贝塞尔曲线绘制与第二次贝塞尔曲线绘制时的参数t,且两者正好范围相同
[外链图片转存中…(img-5RUJyjWi-1664499748428)]
贝塞尔曲面也可类似分段,而如何将这些曲面严丝合缝地拼接起来,此处不作讨论
更多的…
课程内容并未结束,只是我目前并没有时间再继续下去了…