给定一个点列表(x,y),创建一个彼此不靠近的新点列表

时间:2019-02-26 03:00:24

标签: python list distance points closest

我是新手,因此需要帮助: 给定x,y点列表

list=  [(788, 117), (788, 118), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329), (397, 330), (568, 338), (788, 117), (788, 118), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329), (397, 330), (568, 338), (418, 112), (418, 113), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329), (397, 330), (568, 338), (418, 112), (418, 113), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329), (397, 330), (568, 338), (418, 112)

我想创建一个点彼此不靠近的新列表。 示例(788,117),(788,118)彼此靠近。

我相信此功能将有助于找到欧几里得距离:

def dist(p, q):
    "Return the Euclidean distance between points p and q."
    return int(math.hypot(p[0] - q[0], p[1] - q[1]))

提前谢谢

更新:

这是我尝试过的方法,但并没有达到我想要的效果:

import math

list1 = [(788, 117), (788, 118), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329), (397, 330),
         (568, 338), (788, 117), (788, 118), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329),
         (397, 330), (568, 338), (418, 112), (418, 113), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284),
         (397, 329), (397, 330), (568, 338), (418, 112), (418, 113), (516, 164), (799, 171), (453, 225), (740, 284),
         (741, 284), (397, 329), (397, 330), (568, 338), (418, 112)]
list2 = []


def dist(p, q):
    "Return the Euclidean distance between points p and q."
    return int(math.hypot(p[0] - q[0], p[1] - q[1]))


while True:

    for i in list1:
        for j in list1:
            if i not in list2 and dist(i, j) <= 5:
                list2.append(i)

    print("list1 ", list1)
    print("list2 ", list2)

结果: 列表中没有重复的点,似乎变得更具挑战性

list1  [(788, 117), (788, 118), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329), (397, 330), (568, 338), (788, 117), (788, 118), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329), (397, 330), (568, 338), (418, 112), (418, 113), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329), (397, 330), (568, 338), (418, 112), (418, 113), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329), (397, 330), (568, 338), (418, 112)]
list2  [(788, 117), (788, 118), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329), (397, 330), (568, 338), (418, 112), (418, 113)]

列表不断更新,这就是为什么我有一个while循环的原因 我在这里做错了什么

更新:

points =  [(336, 14), (335, 15), (336, 15), (337, 15), (524, 15), (525, 15), (526, 15), (335, 16), (336, 16), (337, 16),
           (525, 16), (526, 16), (336, 17), (706, 19), (705, 20), (706, 20), (707, 20), (705, 21), (706, 21), (707, 21),
           (706, 22), (434, 66), (433, 67), (434, 67), (435, 67), (433, 68), (434, 68), (435, 68), (717, 73), (718, 73),
           (716, 74), (717, 74), (718, 74), (717, 75), (718, 75), (370, 127), (371, 127), (372, 127), (370, 128),
           (371, 128), (372, 128), (371, 129), (600, 129), (601, 129), (602, 129), (601, 130), (602, 130), (485, 140),
           (486, 140), (390, 174), (391, 174), (392, 174), (390, 175), (391, 175), (392, 175), (658, 186), (659, 186),
           (658, 187), (659, 187), (660, 187), (658, 188), (659, 188), (660, 188), (315, 231), (314, 232), (315, 232),
           (316, 232), (314, 233), (315, 233), (316, 233), (485, 240), (486, 240), (487, 240), (485, 241), (486, 241),
           (487, 241), (485, 242), (486, 242), (665, 250), (666, 250), (645, 339), (646, 339), (593, 384), (594, 384),
           (595, 384), (596, 384), (593, 385), (594, 385), (595, 385), (710, 386), (711, 386), (709, 387), (710, 387),
           (711, 387), (712, 387), (709, 388), (710, 388), (711, 388), (712, 388)]

2 个答案:

答案 0 :(得分:0)

您可以使用itertools.combinations查找所有可能的点对,并使用列表推导消除太近的点对。例如:

import itertools
min_distance = 1
my_list =  [(788, 117), (788, 118), (516, 164), (799, 171), ...]
print([pair for pair in itertools.combinations(my_list, 2) if dist(*pair) > min_distance])

答案 1 :(得分:0)

为尽可能提高效率,您应该使用一组已知的点进行短路,以缩短组合生成过程。您也可以使用距离的平方作为标准,以免计算平方根。

在示例点列表中,我注意到您有很多重复项。这意味着重复的每个点都将被排除,因为它与另一个点的距离为零。请注意,这是您的数据和算法都存在的问题。您的算法将检查每个点与其自身之间的距离(结果为零),因此无论如何都将排除所有点。您的第二个for循环只需要匹配列表中 i 点之后的 j 点,并且应同时排除 i j (如果彼此之间距离太近)。

假设您要求的是彼此不靠近的不同个点,那么下面是一个示例:

points =  [(788, 117), (788, 118), (516, 164), (799, 171), (453, 225), (740, 284), (741, 284), (397, 329), (397, 330), (568, 338)]
minimumDistance = 5

from itertools import combinations
tooClose = set()
minDistance2 = minimumDistance * minimumDistance
for point,otherPoint in combinations(list(set(points)),2):
    if point in tooClose and otherPoint in tooClose : continue
    dx,dy = (point[0]-otherPoint[0]), (point[1]-otherPoint[1])
    if (dx*dx+dy*dy) <= minDistance2:
        tooClose.add(point)
        tooClose.add(otherPoint)
result = [point for point in points if point not in tooClose]
print(result)