【问题标题】:How can I count the length of the edge associated with each point?如何计算与每个点关联的边的长度?
【发布时间】:2021-11-25 08:20:05
【问题描述】:

我在 python 中构建了 Delaunay 三角剖分。 现在我有 8 个点(黑色)并生成 14 个边缘(灰色)。 如何计算与每个点关联的边的长度? 我想要的矩阵是每个点连接的边的长度,例如

[[P1, E1_length, E2_length, ...], [P2, E6_length, E7_length, ...], ...]
import numpy as np
points = np.array([[0, 0], [0, 1.1], [1, 0], [1, 1],[1.5, 0.6],[1.2, 0.5],[1.7, 0.9],[1.1, 0.1],])
from scipy.spatial import Delaunay
tri = Delaunay(points)

import matplotlib.pyplot as plt
plt.triplot(points[:, 0], points[:, 1], tri.simplices.copy(), color='0.7')
plt.plot(points[:, 0], points[:, 1], 'o', color='0.3')
plt.show()

【问题讨论】:

    标签: python delaunay


    【解决方案1】:

    新答案

    这是一种方法,可为您提供与每个点相关的点和边长字典:

    simplices = points[tri.simplices]
    edge_lengths = {}
    
    for point in points:
        key = tuple(point)
        vertex_edges = edge_lengths.get(key, [])
        adjacency_mask = np.isin(simplices, point).all(axis=2).any(axis=1)
        for simplex in simplices[adjacency_mask]:
            self_mask = np.isin(simplex, point).all(axis=1)
            for other in simplex[~self_mask]:
                dist = np.linalg.norm(point - other)
                if dist not in vertex_edges:
                    vertex_edges.append(dist)
        edge_lengths[key] = vertex_edges
    

    输出:

    {(0.0, 0.0): [1.4142135623730951, 1.1, 1.3, 1.0],
     (0.0, 1.1): [1.004987562112089, 1.3416407864998738, 1.4866068747318506],
     (1.0, 0.0): [1.4866068747318506, 0.5385164807134504, 0.7810249675906654, 1.140175425099138, 0.14142135623730956],
     (1.0, 1.0): [1.004987562112089, 1.4142135623730951, 0.5385164807134504, 0.6403124237432849, 0.7071067811865475],
     (1.5, 0.6): [0.6403124237432849, 0.36055512754639896, 0.31622776601683794, 0.6403124237432848],
     (1.2, 0.5): [0.5385164807134504, 1.3, 0.31622776601683794, 0.41231056256176607],
     (1.7, 0.9): [0.7071067811865475, 0.36055512754639896],
     (1.1, 0.1): [0.14142135623730956, 0.41231056256176607, 0.6403124237432848]}
    

    要求更改之前的旧答案

    Delaunay 对象有一个simplices 属性,它返回构成单纯形的点。使用scipy.spatial.distance.pdist() 和高级索引,您可以获得所有边长,如下所示:

    >>> from scipy.spatial.distance import pdist
    
    >>> edge_lengths = np.array([pdist(x) for x in points[tri.simplices]])
    >>> edge_lengths
    array([[1.00498756, 1.41421356, 1.1       ],
           [0.53851648, 1.3       , 1.41421356],
           [0.53851648, 1.        , 1.3       ],
           [0.64031242, 0.70710678, 0.36055513],
           [0.64031242, 0.31622777, 0.53851648],
           [0.14142136, 0.53851648, 0.41231056],
           [0.64031242, 0.41231056, 0.31622777]])
    

    但是请注意,这里的边长度是重复的,因为每个单纯形至少与另一个单纯形共享一条边。

    一步一步

    tri.simplices 属性在 points 中为 Delaunay 对象中每个单纯形中的每个顶点提供索引:

    >>> tri.simplices
    array([[2, 6, 5],
           [7, 2, 5],
           [0, 7, 5],
           [2, 1, 4],
           [1, 2, 7],
           [0, 3, 7],
           [3, 1, 7]], dtype=int32)
    

    使用高级索引,我们可以获得构成单纯形的所有点:

    >>> points[tri.simplices]
    array([[[1. , 1. ],
            [0. , 1.1],
            [0. , 0. ]],
    
           [[1.2, 0.5],
            [1. , 1. ],
            [0. , 0. ]],
    
           [[1. , 0. ],
            [1.2, 0.5],
            [0. , 0. ]],
    
           [[1. , 1. ],
            [1.5, 0.6],
            [1.7, 0.9]],
    
           [[1.5, 0.6],
            [1. , 1. ],
            [1.2, 0.5]],
    
           [[1. , 0. ],
            [1.1, 0.1],
            [1.2, 0.5]],
    
           [[1.1, 0.1],
            [1.5, 0.6],
            [1.2, 0.5]]])
    

    最后,这里的每个子数组代表一个单纯形和形成它的三个点,通过使用scipy.spatial.distance.pdist(),我们可以通过迭代单纯形得到每个单纯形中每个点的成对距离:

    >>> np.array([pdist(x) for x in points[tri.simplices]])
    array([[1.00498756, 1.41421356, 1.1       ],
           [0.53851648, 1.3       , 1.41421356],
           [0.53851648, 1.        , 1.3       ],
           [0.64031242, 0.70710678, 0.36055513],
           [0.64031242, 0.31622777, 0.53851648],
           [0.14142136, 0.53851648, 0.41231056],
           [0.64031242, 0.41231056, 0.31622777]])
    

    【讨论】:

    • 通过你的方法,我得到了每个三角剖分顶点的索引和边的长度矩阵。但是我想要的矩阵是每个点连接的边的长度,例如 [[P1, E1_length, E2_length, E3_length, E4_length, E5_length ], [P2, E6_length, E7_length, E1_length, E8_length, E9_length ], ...]
    • @user17075520 我更新了我的答案,但也许你没有看到它。您可以对此代码进行许多修改,具体取决于您想要的输出的确切结构。你想要的[[P1, |E1|, |E2|, ...], ...] 的结果不是特别清楚,因为Pi 是一个(x, y) 坐标,但|Ej| 是一个标量,所以我选择了一个字典,其中字典中的每个键都是三角剖分,值是连接到该点的边的长度列表。
    • 代码: if dist not in vertex_edges: vertex_edges.append(dist) 当不同的边(连接到一个点)长度相同时,边也被删除了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多