数据是空间中的路径。我有3D位置数据(x,y,z)和记录位置点的时间。
x,y和z坐标是穿过3D Space的物体的点位置。时间值是记录每个点的时间(从0开始)。
x y z time(s)
0.1 2.2 3.3 0
2.4 2.4 4.2 0.3
4.5 2.5 1.8 0.6
我最终会错过一些录音活动。 (这是已知的并且被接受为真)并且数据流将以不同的时间间隔继续:
x y z time(s)
0.1 2.2 3.3 0
2.4 2.4 4.2 0.3
//missing x,y,z data point at time 0.6
//missing x,y,z data point at time 0.9
4.5 2.5 1.8 1.2
...
...
请注意数据已简化。我的目标是在已知的丢失时间内插入缺失的3D点。我已经研究了各种插值技术,但我不完全确定哪种插值方法适合我的问题。
1)有人可以简洁地解释这是什么问题吗?我的数学非常生疏,我不确定如何正确描述它,这导致我研究可能不适合的插值技术。2)更新1 由于我没有使用3D空间中的网格,因此不应在此处应用Tricubic插值。我正在研究一个轨迹。我在Apache math3公共中找到了Tricubic Interpolation implementation,但是我不确定这是否是我需要的。如果你查看它所采用的参数,它需要一个我不确定的double [] [] [] fval矩阵。
3)如果不是最适合Java,那么插入这些数据的最佳工具是什么?
更新2 - 有关幽灵解决方案的问题
在您的编辑中,您提供以下有关"匹配关节点的第一个派生的提示":
让我们定义我们的t=<-2,+2>
并像这样对控制点进行采样(并不重要,它会如何影响系数的大小,包括-1,0,1
将使方程式更加轻松化):
p(-2) = p0
p(-1) = p1
p( 0) = p2
p( 1) = p3
现在假设我们想要在t=<0,1>
区间内插入所有点,以便p2
和p3
之间的所有点。并且我们想要连续的分段曲线,因此关节点上的第一个推导应该匹配。我们在左侧还有一个控制点,因此第二个推导也可以匹配:
p'(0) = 0.5*((p3-p2)+(p2-p1)) = 0.5*(p3-p1)
p'(1) = 0.5*((p4-p3)+(p3-p2)) = 0.5*(p4-p2)
p''(0)= 0.5*(((p2-p1)-(p1-p0))+((p4-p3)-(p3-p2)))
= 0.5*((p2-2*p1+p0)+(p4-2*p3+p2))
= 0.5*(p0+p4)-p1+p2-p3
希望我在第二次推导中没有犯任何愚蠢的错误。现在只需用已知控制点替换p(t)
并形成方程组,并从a0,a1,a2,a3,a4
代数计算p0,p1,p2,p3,p4
。
1)joint points
是什么意思?
2)在哪里
p'(0) = 0.5*((p3-p2)+(p2-p1)) = 0.5*(p3-p1)
p'(1) = 0.5*((p4-p3)+(p3-p2)) = 0.5*(p4-p2)
来自哪里?它们与p(0) = p2
和p(1) = p3
有任何关联吗?它们可以是你选择的任何东西吗?
它可以重写为p'(0) = 0.5*((p(3)-p(0)) + (p(0)-p(-1))
正确吗?我不清楚为什么要这样做。或者甚至为什么可以完成
2b)类似的问题
p''(0)= 0.5*(((p2-p1)-(p1-p0))+((p4-p3)-(p3-p2)))
= 0.5*((p2-2*p1+p0)+(p4-2*p3+p2))
= 0.5*(p0+p4)-p1+p2-p3
但我假设澄清问题2)将减轻我对2b)的模糊性,因为我不知道等式来自何处。
接下来是非常简单的,然后它只是方程组
答案 0 :(得分:1)
由于你的数据很可能只是一些平滑的曲线采样点,我会使用这样的三次插值多项式:
曲线属性是这样的,它通过所有控制点(t={-1,0,+1,+2}
),内部控制点的方向(第一次推导)是平坦的连接面平滑连接(类似于 Bezier cubics)。
算法是这样的:
在缺失点前取2分,在
后取2分让我们称呼他们p0,p1,p2,p3
他们理想情况下应该是时间等距的......并按时间排序。
为每个轴计算4个系数
d1=0.5*(p2.x-p0.x);
d2=0.5*(p3.x-p1.x);
ax0=p1.x;
ax1=d1;
ax2=(3.0*(p2.x-p1.x))-(2.0*d1)-d2;
ax3=d1+d2+(2.0*(-p2.x+p1.x));
d1=0.5*(p2.y-p0.y);
d2=0.5*(p3.y-p1.y);
ay0=p1.y;
ay1=d1;
ay2=(3.0*(p2.y-p1.y))-(2.0*d1)-d2;
ay3=d1+d2+(2.0*(-p2.y+p1.y));
d1=0.5*(p2.z-p0.z);
d2=0.5*(p3.z-p1.z);
az0=p1.z;
az1=d1;
az2=(3.0*(p2.z-p1.z))-(2.0*d1)-d2;
az3=d1+d2+(2.0*(-p2.z+p1.z));
将参数t=<0,1>
设置为与缺失时间相对应的值
因此,如果您选择时间为p0,p1,p2,p3
的分数t0,t1,t2,t3
,那么缺失的时间tm
将对应于参数:
t = (tm-t1)/(t2-t1);
计算缺失点。
x=ax0+ax1*t+ax2*t*t+ax3*t*t*t
y=ay0+ay1*t+ay2*t*t+ay3*t*t*t
z=az0+az1*t+az2*t*t+az3*t*t*t
如果通过导出类似的方程式或拟合,这是不够的,则可以使用更高阶的多项式。另外看看这个:
[Edit1]构建自己的多项式
您的评论的答案位于Impact of cubic and catmull splines on image的 [edit2] ,该链接也在上面的上一个链接中链接。要以类似的方式制作4度插值多项式,您将得到5个点(p0,p1,p2,p3,p4)
和方程式:
p(t)= a0 + a1*t + a2*t*t + a3*t*t*t + a4*t*t*t*t
p'(t) = a1 + 2*a2*t + 3*a3*t*t + 4*a4*t*t*t
p''(t) = 2*a2 + 6*a3*t +12*a4*t*t
让我们定义我们的t=<-2,+2>
并像这样对控制点进行采样(并不重要,它会如何影响系数的大小,包括-1,0,1
将使方程式更加轻松化):
p(-2) = p0
p(-1) = p1
p( 0) = p2
p( 1) = p3
p( 2) = p4
现在假设我们想要在t=<0,1>
区间内插入所有点,以便p2
和p3
之间的所有点。并且我们想要连续的分段曲线,因此关节点上的第一个推导应该匹配。我们在左侧还有一个控制点,因此第二个推导也可以匹配:
p'(0) = 0.5*((p3-p2)+(p2-p1)) = 0.5*(p3-p1)
p'(1) = 0.5*((p4-p3)+(p3-p2)) = 0.5*(p4-p2)
p''(0)= 0.5*(((p2-p1)-(p1-p0))+((p4-p3)-(p3-p2)))
= 0.5*((p2-2*p1+p0)+(p4-2*p3+p2))
= 0.5*(p0+p4)-p1+p2-p3
希望我在第二次推导中没有犯任何愚蠢的错误。现在只需用已知控制点替换p(t)
并形成方程组,并从a0,a1,a2,a3,a4
代数计算p0,p1,p2,p3,p4
。提示使用t=0,t=+1
和t=-1
,这样您就可以获得线性方程式。例如:
p( 0) = p2 = a0 + a1*0 + a2*0*0 + a3*0*0*0 + a4*0*0*0*0
p2 = a0
正如您所看到的,计算a0
的确非常简单,可以用于派生:
p'(0) = 0.5*(p3-p1) = a1 + 2*a2*0 + 3*a3*0*0 + 4*a4*0*0*0
p''(0)= 0.5*(p0+p4)-p1+p2-p3 = 2*a2 + 6*a3*0 +12*a4*0*0
-------------------------------------------------------------------
0.5*(p3-p1) = a1
0.5*(p0+p4)-p1+p2-p3 = 2*a2
-------------------------------------------------------------------
0.5*(p3-p1) = a1
0.25*(p0+p4)-0.5*(p1+p2-p3) = a2
-------------------------------------------------------------------
现在使用t=+1
和t=-1
并计算a3,a4
。您可以设置关节点派生以满足您的特定需求(不仅仅是从左侧和右侧推导的平均值),而是像您一样形成连续曲线这是最好的(根据我的经验)。