如何在Python中比较两条3D曲线?

时间:2018-08-07 15:33:13

标签: python computational-geometry curve-fitting

我有一个巨大的数组,带有描述3D曲线的坐标,大约20000点。我正在尝试使用较少的积分,而忽略一些积分,比如说每2积分取1。当我这样做并绘制减少的点数时,形状看起来相同。但是,我想正确比较两条曲线,类似于卡方检验,以查看缩小的图与原始图有多少不同。

是否有一种简单的内置方法来执行此操作,或者是否有人对如何解决此问题有任何想法。

2 个答案:

答案 0 :(得分:2)

“线简化”的一般问题似乎是整个研究领域。我建议您看一下Ramer–Douglas–Peucker algorithm。我可以找到几个python模块:rdpsimplification(它们也实现了Py-Visvalingam-Whyatt algorithm)。

无论如何,我正在尝试使用插值法来评估两条折线之间的差异。即使没有公共点,也可以比较任何曲线。

第一个想法是计算两条折线沿路径的距离。它们被用作从第一条曲线上的一个给定点到另一条曲线上的一个相对较近点的界标。

然后,可以将第一条曲线的点插值到另一条曲线上。现在可以逐点比较这两个数据集。

在图上,黑色曲线是xy2在曲线xy1上的插值。因此,可以计算出黑色正方形橙色圆圈之间的距离并进行平均。

这给出了一个平均距离度量,但是没有什么可与之进行比较并确定所应用的缩减是否足够好...

example graph

def normed_distance_along_path( polyline ):
    polyline = np.asarray(polyline)
    distance = np.cumsum( np.sqrt(np.sum( np.diff(polyline, axis=1)**2, axis=0 )) )
    return np.insert(distance, 0, 0)/distance[-1]

def average_distance_between_polylines(xy1, xy2):   
    s1 = normed_distance_along_path(xy1)
    s2 = normed_distance_along_path(xy2)

    interpol_xy1 = interp1d( s1, xy1 )
    xy1_on_2 = interpol_xy1(s2)

    node_to_node_distance = np.sqrt(np.sum( (xy1_on_2 - xy2)**2, axis=0 ))

    return node_to_node_distance.mean() # or use the max

# Two example polyline:
xy1 = [0, 1, 8, 2, 1.7],  [1, 0, 6, 7, 1.9]   # it should work in 3D too
xy2 = [.1, .6, 4, 8.3, 2.1, 2.2, 2],  [.8, .1, 2, 6.4, 6.7, 4.4, 2.3]

average_distance_between_polylines(xy1, xy2)  # 0.45004578069119189

答案 1 :(得分:1)

如果对原始曲线进行二次采样,则评估近似误差的一种简单方法是计算原始曲线与重新采样的顶点之间的线段之间的最大距离。最大距离出现在原始顶点,仅在这些点就可以求值。

顺便说一句,这提供了一种简单的方法来执行子采样,方法是设置最大容差并抽取直到超出容差为止。

您也可以考虑计算平均距离,但这可能涉及讨厌的积分,并且可能会带来不太令人满意的视觉效果。