介绍
埃尔米特曲线是非常有用和容易计算,常被用于关键点的平滑插值,了解埃尔米特曲线的数学原理将会对你了解整个样条曲线族有很大的帮助,可能你在没有了解它之前已经在3D程序实现过他。
原理
让我们从一些简单的原理开始吧,我们同样也讨论一些二维曲线,如果你需要处理一些三维曲线仅仅需要像处理X坐标和Y坐标一样处理Z坐标,埃尔米特可以在多维空间中实现。
P1: 曲线的开始点
T1: 切线(方向和速度)描述曲线如何离开开始点
P2: 曲线结束点
T2: 切线(方向和速度)描述曲线如何达到结束点.
四个与埃尔米特相关的基本函数
函数对应的曲线,所有曲线除了第四个都是从0.0到1.0绘制
我们仔细看一下函数h1和h1:
H1 从1到0减速递减
H2 从0到1加速递增
我们将开始点结束点分别乘以h1 h2 ,让s从0到1递增插值开始点和结束点,h3和h4作为切线也同样处理,这样就能确保曲线开始点和结束点能够按我们想要的方向弯曲.
矩阵的形式
所有的公式都能用向量和矩阵来表现,我认为矩阵形式是一个比较容易理解的方式
向量 S:插值关键点
向量 C:埃尔米特曲线的参数
矩阵 h: 埃尔米特多项式的矩阵形式
插值点 P = S * H * C
一些补充: 贝塞尔曲线
矩阵对又有的三次多项式曲线都有效,唯一的区别就是多项式矩阵.,假如你需要绘制贝赛尔曲线你可能需要一下矩阵
等内容,可以查看 bezier curves
一些伪代码
没错,一些C类型的语言不能编译, C不能编出强大的功能,你可能自己编写出了无数错误的向量,以至于认为自己是个傻瓜,我想展示一些更高层的代码或许对你有些帮助
moveto (P1); // move pen to startpoint
for (int t=0; t < steps; t++)
{
float s = (float)t / (float)steps; // scale s to go from 0 to 1
float h1 = 2s^3 - 3s^2 + 1; // calculate basis function 1
float h2 = -2s^3 + 3s^2; // calculate basis function 2
float h3 = s^3 - 2*s^2 + s; // calculate basis function 3
float h4 = s^3 - s^2; // calculate basis function 4
vector p = h1*P1 + // multiply and sum all funtions
h2*P2 + // together to build the interpolated
h3*T1 + // point along the curve.
h4*T2;
lineto (p) // draw to calculated point on the curve
}
攻克切线
我知道如何计算切线是相当的不简单,这是很难控制曲线的形状的,同样,为了让曲线变得不那么突兀,我们必须让切线远离曲线?我将介绍如何将埃尔米特曲线装换为基数样条
基数样条
基数样条金石埃尔米特的曲线的子集,我们并需要切线,因为他们会帮我们从关键点中计算,当然,我们也将失去一些可能性,但是非常容易去计算使用
公式: Ti = a ( p(i+1) – p(i-1))
简单? 不是吗,试着看一下数学书中的卡特莫尔-ROM样条,你会发现他说如此的变态难,但是当我们把基数样条从卡特莫尔-ROM样条从剥离出来,那是相当的简单。但是,当你有一大堆关键点并且要去平滑插值他们时,就是卡特莫尔-ROM样条了
巴特尔斯样条曲线(TCB样条曲线)
现在,我们将鼓起勇气继续我们的曲线插值,巴特尔斯样条曲线(用于3Dmas和LightWave软件)无非就是埃尔米特曲线和一写处理切线的方法而已,不必为他那常常的名字而纠结,这些曲线是由 D. Kochanek and R. Bartels 实现,用于使动画的关键帧更多的控制,他们为关键帧实现三种控制值
开始点切线
结束点切线
当你插值时你可以使用它
你可能会发现你总是需要开始点和结束点但你计算插值时,这可能导致一些问题当你计算插值点时,我不知道这些程序是如何在开始点和结束点中处理的,但是我知道网上有足够有效的资源,仅仅需要的是 搜一下
速度控制
如果你把你自己的插值算法写入程序中你会发现一个问题,,除非你插值点取值是固定的时间间隔,否则当你通过某个关键点是它会出现速度和方向的突变,如果你采用两帧之间的关键帧去计算,则可以避免这个问题
N是两个控制点之间帧的总数
结束点切线的调整
开始点切线的调整
一些”正常”曲线
其他像基本样条,β-样条曲线,均匀的非理性的样条和其它样条与此的不同,所以没有包括进来,但是它们和埃尔米特曲线有一个共同点: 他们都是三次多项式,只是计算方法不同
原版英文来自 http://cubic.org/docs/hermite.htm
2013-8-21