我有一个线段的列表,每个线段的x和y坐标分别是其“从”和“到”点,如下所示(下面的示例被截断了,很长)。
[
{'f': {'x': 15.0, 'y': -5.0}, 't': {'x': 16.0, 'y': -5.0}},
{'f': {'x': 3.0, 'y': -7.0}, 't': {'x': 5.0, 'y': -7.0}},
{'f': {'x': 9.0, 'y': -7.0}, 't': {'x': 10.0, 'y': -7.0}},
{'f': {'x': 10.0, 'y': -4.0}, 't': {'x': 10.0, 'y': -5.0}},
{'f': {'x': 9.0, 'y': -4.0}, 't': {'x': 10.0, 'y': -4.0}},
{'f': {'x': 4.0, 'y': -4.0}, 't': {'x': 5.0, 'y': -4.0}},
...
]
我还有一个函数lines_connected
,它将这些列表项(行)中的两个作为其a
和b
参数,如果结束则返回True
每条线的另一条线都在另一条线的一部分上(但False
如果它们只是相交而一条线没有在另一条线的尽头,或者它们根本不“接触”)。使用此方法,我需要找到如上所述“连接”的所有行组(大概是列表中的列表)。并非组内的所有线路都必须直接与其他线路直接连接,而是通过组内的其他线路连接。
将这些行分组为这些“连接的组”的最佳方法是什么?
答案 0 :(得分:2)
一种执行此操作的方法是使用基于网络的方法。您可以为此使用networkx。
在此设置中,每个线段都是一个节点,lines_connected
的输出将确定它们之间是否存在边。因此,如果lines_connected
在a
和b
的任何两个段上显示True,则可以在两个节点之间创建边。否则你就没有了。
最后,您可以通过使用连接的子组件图来获得“连接的组”
import networkx as nx
#G would be your Node-Edge Graph created with line segments and the outuput of lines_connected
sub_graphs = nx.connected_component_subgraphs(G)
答案 1 :(得分:1)
这是一个图形问题。您可以轻松地将列表转换为networkx图,端点为节点,线段为边:
import networkx as nx
def to_xy(p, key='f'):
d = p[key]
return (d['x'], d['y'])
segments = [...]
g = nx.Graph()
for seg in segments:
g.add_edge(to_xy(seg, 'f'), to_xy(seg, 't'), obj=seg)
作为参考,我在每个边上添加了一个obj
属性,该属性指向用于构造它的原始字典。
现在要获取组,您要做的就是获取图形的connected components:每个组件内的边将是相互连接的线段。这些可以根据不推荐使用的connected_component_subgraphs
方法的描述获得:
components = map(g.subgraph, nx.connected_components(g))
edges = [list(nx.get_edge_attributes(sg, 'obj').values()) for sg in components]
要检查是否以某种方式连接了两个点,只需检查从一个起点到另一个起点之间是否有path,例如here:
nx.has_path(g, to_xy(s1), to_xy(s2))
对于端点使用f
还是t
都没关系。