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

时间:2017-07-06 18:12:51

标签: java math 3d interpolation

数据是空间中的路径。我有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>区间内插入所有点,以便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)并形成方程组,并从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) = 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)的模糊性,因为我不知道等式来自何处。

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

1 个答案:

答案 0 :(得分:1)

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

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

算法是这样的:

  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>设置为与缺失时间相对应的值

    因此,如果您选择时间为p0,p1,p2,p3的分数t0,t1,t2,t3,那么缺失的时间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
    
  5. 如果通过导出类似的方程式或拟合,这是不够的,则可以使用更高阶的多项式。另外看看这个:

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