通过多点平滑曲线的实现
通过多点平滑曲线的实现
大家都知道使用贝塞尔曲线算法来画曲线,但是如果想经过特定的一系列点来画曲线,只使用普通的贝塞尔算法就不够用了.
通过参考网上文章:https://www.jianshu.com/p/64305821087a
确定了实现方法要点:
1 在连续两点之间使用三次贝塞尔曲线来绘制.
2 为了保证两段贝塞尔之间的圆滑,连接点对应的两个控制点与曲线相切.
然后剩下的问题就是确定每个点所连接点的角度,参考上面的文章实现功能,但是发现这篇文章确定控制点角度的是通过计算斜率来实现.这样连续两点X轴相等的时候,就会出现问题.它所提供的算法只适应X单向增长的环境.如果需要普遍适应,需要进一步的处理,其后虽然实现适应性,但是斜率的计算非常不清晰不利于调整绘制曲线的样式.
计算斜率,就是确定每个点法线的角度.发现使用向量来计算法线,更加便捷和清晰.
将连续的三点{p1 , p2 ,p3} 以p1点为原点,获得两个向量:
v1 = p1->p2
v2 = p1 ->p3
做v1 v2的和:
v3 = v1 + v2
v3加在v1与v2之间,完全符合p1点法线的要求.由于p1点的切线斜率受到v1向量的影响大,v2向量的影响小,最后确定p1点的切线向量公式为:
v3 = 2v1 + v2
p1点前后两个控制点,在一条直线上,那么另外一个控制点的向量就是简单的 -v3
然后根据p1点前后两个线段长度决定两个权值l1 和 l2
将v3单位化
获得p1的两个控制点:
p1_forward = p1 + l1 * v3
p1_backward = p1 - l2v3
按照这个方面获得所有点的控制点.
然后使用贝塞尔方法,依次绘制曲线.
每个三次贝塞尔曲线的序列为[p1,p1_forward ,p2_backward,p2]
代码为python实现,csdn下载中搜"通过多点平滑曲线的python实现"
以后需要完善的有两个方面:
1 实现曲线的闭合.现在闭合点没有圆滑过渡.并不能简单后点循环接到前点来计算斜率,需要一直循环下去直到找到斜率误差小于一定值的点停止.
2 相邻非常近的点,在实现的时候是否给合并处理.需要在实现中加入精度参数.
贝塞尔算法的实现来自于:
https://github.com/TheAlgorithms/Python/blob/master/graphics/bezier_curve.py
最后补充一下,这种方法实现三维的连续曲线也是可以的,只要找到三维的贝塞尔算法实现,然后把上面的二维的向量改为三维向量就可以了.