首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何计算与每个点关联的边的长度?

如何计算与每个点关联的边的长度?
EN

Stack Overflow用户
提问于 2021-10-05 01:22:17
回答 1查看 97关注 0票数 1

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

代码语言:javascript
复制
[[P1, E1_length, E2_length, ...], [P2, E6_length, E7_length, ...], ...]
代码语言:javascript
复制
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()

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-05 02:50:43

新答案

这里有一种方法,它将给你一个点和与每个点相关的边长度的字典:

代码语言:javascript
复制
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

输出:

代码语言:javascript
复制
{(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()和高级索引,您可以获得所有的边长度,如下所示:

代码语言:javascript
复制
>>> 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]])

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

循序渐进

Delaunay属性给出了tri.simplices对象中每个单形中每个顶点的索引(以points表示):

代码语言:javascript
复制
>>> 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)

使用高级索引,我们可以获得组成简化的所有点:

代码语言:javascript
复制
>>> 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(),我们可以通过迭代单形得到每个单形中每个点的成对距离:

代码语言:javascript
复制
>>> 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]])
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69443921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档