在已知的缺失时间间隔之间插值3D坐标

数据是空间中的路径。 我有3D位置数据(x,y,z)和记录位置点的时间。

x,y和z坐标是穿过3D Space的物体的点位置。 时间值是记录每个点的时间(从0开始)。

xyz 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 

我最终会错过一些录音活动。 (这是已知的并且被接受为真)并且数据流将以不同的时间间隔继续:

 xyz 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 Tricubic插值不应该适用于此,因为我没有使用3D空间中的网格。 我正在研究一个轨迹。 我在Apache math3 commons中找到了一个Tricubic Interpolation实现 ,但是我不确定这是否是我需要的。 如果你看看它所采用的参数,它需要一个我不确定的double [] [] [] fval矩阵。

3)如果不是最适合Java,那么插入这些数据的最佳工具是什么?

更新2 – 有关Spectre解决方案的问题

在您的编辑中,您提供以下有关“匹配关节点的首次推导”的提示:

让我们定义我们的t=并像这样对控制点进行采样(它实际上不会影响系数的大小,包括-1,0,1会使方程式很多):

 p(-2) = p0 p(-1) = p1 p( 0) = p2 p( 1) = p3 

现在假设我们想要插入区间t=所有点,以便p2p3之间的所有点。 并且我们想要连续的分段曲线,因此关节点上的第一个推导应该匹配。 我们左侧还有一个控制点,所以第二个推导也可以匹配:

 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)并形成方程组,并从p0,p1,p2,p3,p4代数计算a0,a1,a2,a3,a4

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) = p2p(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)的模糊性,因为我不知道方程式来自哪里。

接下来是非常简单的,然后它只是方程组

由于您的数据很可能只是一些平滑的曲线采样点,我会使用如下的三次插值多项式:

  • C#/ Unity3D中的分段线性整数曲线插值

曲线属性是这样的,它通过所有控制点( t={-1,0,+1,+2} ),内部控制点的方向(第一次推导)是平滑的连接侧面(类似于Bezier)生成立方体)。

算法是这样的:

  1. 丢失点前2分,后2分

    让我们称它们为p0,p1,p2,p3它们理想情况下应该是时间等距的……并按时间排序。

  2. 计算每个轴的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)); 
  3. 将参数t=<0,1>为与缺失时间对应的值

    所以如果你用时间t0,t1,t2,t3选择点p0,p1,p2,p3那么缺失时间tm对应于参数:

     t = (tm-t1)/(t2-t1); 
  4. 计算缺失点。

     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]构造自己的多项式

您的评论的答案在[edit2]的立方和catmull样条曲线对图像的影响,这也在上面的上一个链接中链接。 要以类似的方式制作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>所有点,以便p2p3之间的所有点。 并且我们想要连续的分段曲线,因此关节点上的第一个推导应该匹配。 我们左侧还有一个控制点,所以第二个推导也可以匹配:

 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)并形成方程组,并从p0,p1,p2,p3,p4代数计算a0,a1,a2,a3,a4 。 提示使用t=0,t=+1t=-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=+1t=-1并计算a3,a4 。 您可以设置关节点派生以满足您的特定需求(不仅仅是从左和右推导的平均值),而是像您一样形成连续曲线这是最好的(根据我的经验)。