两点三次埃尔米特插值法

怎样用画笔画光滑曲线-两点三次埃尔米特插值法(转自http://blog.sina.com.cn/s/blog_a8192bdd010105rx.html)

求几点(3点以上)之间的光滑曲线是有很多办法的,如果需要曲线通过目标点,可以用经典的三次样条曲线,如果不需要曲线通过目标点,可以使用贝塞尔曲线。
例如,用三次样条曲线,只要有4点,并且确定两边界点的斜率,既可以求得通过4点的光滑曲线,曲线在各端点处有2阶光滑性。至于三次样条曲线的公式及算法,可以随便买一本《数值分析》研究一下。

但我这几天遇到的问题是,通过画笔绘制曲线时,要绘制成光滑曲线。
画笔的绘制同已知几点求光滑曲线不同,画笔要求的是实时绘制,也就是说画笔走到哪就要把光滑曲线画到哪,这里如果使用三次样条曲线,局限性就在于,以下图为例:
两点三次埃尔米特插值法_第1张图片
当画笔走到B时,只有AB两个端点,这时就要画出AB之间的曲线(实时性),而三次样条曲线要求有3点以上,这时就无法通过三次样条曲线绘制出AB之间的光滑曲线。
其实可以变通一下,在画笔走到C的时候(而不是走到B时)才画出曲线,也就是曲线和画笔的位置有一步的延迟,这样走到C的时候就可以确定ABC三点。
但是这里还存在一个问题,三次样条曲线需要制定两端点的斜率,当画笔走到C时,如果要画出ABC之间的光滑曲线,需要知道A点的斜率和C点的斜率,当画笔走到D时,需要知道B点的斜率和D点的斜率。
其实A点和B点这种(不是最后一个端点)的斜率还是可以给出的,但C点和D点这种最后一个端点的斜率缺无法给出,因为当画笔走到C时,无法确定下一个D点的位置,所以无法确定CD的斜率,也就没有办法确定C点的斜率。
也曾考虑过当画笔走到D点时再绘制前3点的曲线,但是如果这样,那么假设存在下一点E,那么走到E的时候,ABC之间的曲线已经存在,这个时候仅需要绘制CD之间的曲线,又和以开始的绘制3点之前曲线有冲突。延伸下去考虑,其实在D点以后,问题已经演变为画亮点之间光滑曲线,因此把前3个点的问题也转化为2点之间光滑曲线的问题。
可以考虑的方法是:
1、前提条件是曲线永远比画笔延迟一步(这在实际绘制过程中用户是完全察觉不到的)。
2、当走到C点时,绘制AB的曲线,走到D点时,绘制BC的曲线。
3、两点之间的光滑曲线使用“两点三次埃尔米特”公式求曲线方程。
由于两点三次埃尔米特方程也需要给定两端点的斜率,因此问题又回到求斜率的问题上。
继续思考一下,假设A点是起始点,那么画笔走到C时要绘制AB两点之间光滑曲线,需要给定A点和B点的斜率,由于A点是开始点,所以给定斜率比较麻烦(也不是不可能),可以将问题转化为起始点A的斜率等于直线AB的斜率。
那么B点的斜率是什么样呢,由图可知B点斜率介于AB斜率和BC斜率之间,所以可以近似取为AB和BC斜率的一半(AB和BC的中间线)。这样就可以通过两点三次埃尔米特公式计算出AB两点间的曲线了(实际上根据这个方法绘制的AB间为直线)。
继续走到D点,走到D点时需要绘制BC点的曲线,由于在C点时已经计算了B点斜率为AB、BC的中间线,所以B点斜率已知,同样方法可以取C点斜率为BC、CD中间线为C点斜率,这样已知BC两点斜率再通过两点三次埃尔米特公式即可求得BC之间曲线方程。
以此类推可以跟踪画笔绘制出光滑曲线。
本方法的局限性有3:
1、B点处1阶、2阶导数不连续(因为AB为直线,而BC为三次曲线),可以通过近似给得A点斜率方法弥补,不做赘述。
2、曲线始终滞后画笔一个步骤(这在实际中用户无法感觉到)。
3、由于中间端点的斜率始终取为两条相交直线的中心线,所以理论上相对于三次样条曲线不够精确(也许光滑度和曲线形状上欠佳)。
但实际根据以上思路实现之后发现基本上是感觉不到局限性的,所绘制曲线比较另人满意。
由于本人水平有限,还没有考虑出更好的方法跟踪画笔绘制出光滑曲线。也许本文提到的方法可以进一步优化。我会继续研究。

你可能感兴趣的:(ios)