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

How to compare two 3D curves in Python?

我有一个巨大的数组,其中包含描述 3D 曲线的坐标,约 20000 个点。我试图通过忽略一些点来减少点数,比如每 2 点取 1 点。当我这样做并绘制减少的点数时,形状看起来是一样的。不过我想比较一下两条曲线,类似于卡方检验,看看缩小后的图与原来的图有多少不同。

是否有一种简单的内置方法可以做到这一点,或者有人对如何解决这个问题有任何想法。

"line simplification" 的一般问题似乎是整个研究领域。例如,我建议您查看 Ramer–Douglas–Peucker algorithm. There are several python modules, I could find: rdp and simplification (which also implement the Py-Visvalingam-Whyatt algorithm).

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

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

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

图中黑色曲线是xy2在xy1曲线上的插值。所以 黑色方块 橙色圆圈 之间的距离可以计算出来,并求平均。

这给出了一个平均距离测量值,但没有什么可以比较和决定应用的减少是否足够好...

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

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

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

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