检查点之间最近距离的最快方法

时间:2016-08-07 16:28:38

标签: python distance maya points

我有2个词典。两者都具有索引和世界空间位置的键值对。

类似的东西:

{
  "vertices" : 
  {
    1: "(0.004700, 130.417480, -13.546420)",
    2: "(0.1, 152.4, 13.521)",
    3: "(58.21, 998.412, -78.0051)"
  }
}

词典1总是有大约20-100个词条,词典2总是有大约10,000个词条。

对于字典1中的每个点,我想找到字典2中最接近它的点。这样做的最快方法是什么?对于字典1中的每个条目,循环遍历字典2中的所有条目并返回最接近的条目。

一些未经测试的伪代码:

for point, distance in dict_1.iteritems():
    closest_point = get_closest_point(dict_1.get(point))


def get_closest_point(self, start_point)

    furthest_distance = 2000000
    closest_point = 0

    for index, end_point in dict_1.iteritems():
        distance = get_distance(self, start_point, end_point)
        if distance < furthest_distance:
            furthest_distance = distance
            closest_point = closest_point

    return closest_point

我觉得这样的事情会起作用。 “问题”是如果我在字典1中有100个条目,那么它将是100 x 10,000 = 1,000,000次迭代。这对我来说似乎不是很快或很优雅。

在Maya / Python中有更好的方法吗?

编辑: 只是想评论一下我之前使用过的nearestPointOnMesh节点,如果你要检查的点实际上是网格的一部分,它可以很好地工作。你可以这样做:

selected_object = pm.PyNode(pm.selected()[0])
cpom = pm.createNode("closestPointOnMesh", name="cpom")

for vertex, distance in dict_1.iteritems():
    selected_object.worldMesh >> cpom.inMesh

    cpom.inPosition.set(dict_1.get(vertex))
    print "closest vertex is %s " % cpom.closestVertexIndex.get()

来自节点的即时回复,一切都很花哨。但是,如果您要检查的点列表不是网格的一部分,则无法使用此列表。它实际上是否可能/更快:

  • 使用字典2中的点构建网格
  • 使用带有nearestPointOnMesh节点的网格
  • 删除网格

2 个答案:

答案 0 :(得分:1)

你肯定需要一个加速结构来获得非平凡的点数。您想要的是KD树或八叉树 - KD树在搜索时性能更高,但构建速度更慢,编码更难。此外,由于八分之一是空间而不是二进制,因此可以更容易地进行琐碎的测试。

你可以在这里获得一个python八叉树:http://code.activestate.com/recipes/498121-python-octree-implementation/

如果您正在进行大量的距离检查,那么您肯定希望使用Maya API矢量类来进行实际的数学运算比较 - 这将比同等的python更快,更快。如果您不熟悉API,可以从pymel.datatypes获取这些内容,尽管使用较新的API2版本非常轻松。

答案 1 :(得分:0)

您需要所谓的KD树。使用第二个字典中的点构建KD树,并查询第一个字典中每个点的最近点。

我对maya不熟悉,如果你可以使用scipy,你可以使用this

PS:C ++中似乎有一个实现here