写在前面
最初是想要把传统的柱状频谱图做成平滑曲线连接的,“呼吸”效果应该会更自然
之前试过了最小二乘法曲线拟合,结论是最小二乘法曲线拟合不能解决这个问题:
最小二乘法曲线拟合:可以求出一条直线/n次曲线,把所有散点均匀地分为两部分
贝塞尔曲线:可以求出一条曲线平滑穿过各个散点
一.问题重述
三次贝塞尔曲线需要2个控制点,如下图:
3次bezier曲线
(图中的P1, P2是控制点)
通过Audio API可以获取各个散点(柱状频谱图的各个柱子的顶端),而难点就是求2个控制点,随便定是肯定不行的,效果会非常差
二.解决方案
找到了一个基于经验实践的解决方案,没有严格的数学依据,但实际效果很完美,具体步骤如下:
假设控制点在(x1,y1)和(x2,y2)之间,第一个点和最后一个点分别是曲线路径上的上一个点和下一个点
求中点
求各中点连线长度
求中点连线长度比例(用来确定平移前p2, p3的位置)
平移p2
平移p3
[可选]微调控制点与顶点之间的距离,越大曲线越平直
三.JavaScript求三次贝塞尔曲线的控制点
原版是Java实现,笔者做了简单修改封装,如下: