目标
工作需要,需要达成这样得一个需求,给一系列得三维点,三维点按照顺序连接,形成一条折线。需要依照这条折线,进行曲线1m等距离插值。具体如下图
其中,红色圆圈点为原始点集OrigPoints(原始点集找不着了,随手画得,大差不差,以下简称OP), 其他点为等距离1m插值出来得插值点集ResultPoint(以下,简称RP)。
三次样条曲线插值(cubic spline)
本文主要描述一个应用实例,因此,不写具体得公式(主要是懒),主要描述实例应用的原理。
插值与拟合
简要得说,插值指,求得方程严格得通过每一个已知样本点(OP),拟合指,求得方程只求神似,不一定要严格通过每个OP
原理
更具体得原理,大家去自己用google一下baidu结果。
简要描述:将OP分割为多个区间,每个区间内都是一个三次方程式,同时要保证曲线平滑。即,每个区间内可以构建如下形式得方程式:
y
=
a
+
b
x
+
c
x
2
+
d
x
3
=
f
(
x
)
y = a + bx + cx^2 + dx^3 = f(x)
y=a+bx+cx2+dx3=f(x)
与此同时,f‘(一阶导数),f’‘ (二阶导数),f(本身)均连续。
至此,可以知道,我们得目标其实就是每个区间都解算出a、b、c、d这四个参数(如果点数为n + 1,那么可划分为n个区间,则需要结算4n个参数)
emmm,实在是不想打公式,具体参考三次样条插值公式
链接得帖子很好,很nice,一定要看,不看别怪我
与实例结合
原理其实就那样,各种推导公式,得出如下得一个矩阵:
A
m
=
B
.
Am = B.
Am=B.
更重要得是跟实际结合来解决我们得问题,其实cubic spline本身已经使用很广泛了,github上有很好得开源得类,大家都可以去下载使用以下,使用起来也是很简单,就一个单独得.h文件即可,没有任何依赖。
需要注意得点:
单调性:
spline得一个首要条件就是,x是要单调递增。因此,如果单纯的只是使用原始点集进行方程式求解,需要将x旋转至单调递增的空间,再进行操作。
而我的需求,是以距离1m进行均匀内插。为了同时满足单调性,以及均匀内插,将二维的线方程
公
式
1
:
y
=
f
(
x
)
公式1:y = f(x)
公式1:y=f(x)
变成成为
公
式
2
:
x
=
x
(
t
)
,
y
=
y
(
t
)
公式2: x = x(t), y = y(t)
公式2:x=x(t),y=y(t)
其中,t为距离起点的折线长度(注意是折线长度,不是单纯的当前点与起点的欧氏距离),x(t),y(t),分别为x、y关于t的函数
如果是三维线的话,线方程为:
z
=
f
(
x
,
y
)
z = f(x, y)
z=f(x,y)
变成为:
x
=
x
(
t
)
,
y
=
y
(
t
)
,
z
=
z
(
t
)
x = x(t), y = y(t), z = z(t)
x=x(t),y=y(t),z=z(t)
那么,原始的输入点集{(xi, yi,zi)},就变成了两个中间输入点集P1 = {(ti, xi)}、P2 = {(ti,yi)}、P3 = {(ti, zi)},此时,P1、P2、P3分别满足spline 的单调性,依照P1、P2、P3分别进行参数结算之后得到线方程组Func1, Func2, Func3,此时,只需要令ti = 1 、2…n(小于等于OP总长度),分别求出对应的xi, yi,zi,即可获取均匀内插之后的(xi, yi,zi)