给定一组坐标为x和y的二维数据点(左图),是否有一种简单的方法可以在其上构建一个三角形网格(右图)?即返回一个元组列表,指示哪些顶点是连接的。解决方案不是唯一的,但任何合理的网格都可以满足要求。
x
y
vyswwuz21#
您可以使用scipy.spatial.Delaunay。以下是
import numpy as np points = np.array([[-1,1],[-1.3, .6],[0,0],[.2,.8],[1,.85],[-.1,-.4],[.4,-.15],[.6,-.6],[.9,-.2]]) from scipy.spatial import Delaunay tri = Delaunay(points) import matplotlib.pyplot as plt plt.triplot(points[:,0], points[:,1], tri.simplices) plt.plot(points[:,0], points[:,1], 'o') plt.show()
下面是与您的输入类似的结果:
三角形存储在Delaunay对象的simplices属性中,该对象引用存储在points属性中的坐标:
simplices
points
>>> tri.points array([[-1. , 1. ], [-1.3 , 0.6 ], [ 0. , 0. ], [ 0.2 , 0.8 ], [ 1. , 0.85], [-0.1 , -0.4 ], [ 0.4 , -0.15], [ 0.6 , -0.6 ], [ 0.9 , -0.2 ]]) >>> tri.simplices array([[5, 2, 1], [0, 3, 4], [2, 0, 1], [3, 0, 2], [8, 6, 7], [6, 5, 7], [5, 6, 2], [6, 3, 2], [3, 6, 4], [6, 8, 4]], dtype=int32)
如果要查找连接的顶点,则还有一个包含该信息的属性:
>>> tri.vertex_neighbor_vertices (array([ 0, 4, 7, 12, 16, 20, 24, 30, 33, 36], dtype=int32), array([3, 4, 2, 1, 5, 2, 0, 5, 1, 0, 3, 6, 0, 4, 2, 6, 0, 3, 6, 8, 2, 1, 6, 7, 8, 7, 5, 2, 3, 4, 8, 6, 5, 6, 7, 4], dtype=int32))
isr3a4wc2#
您可以尝试scipy.spatial.Delaunay。从该链接:
points = np.array([[0, 0], [0, 1.1], [1, 0], [1, 1]]) from scipy.spatial import Delaunay tri = Delaunay(points) plt.triplot(points[:,0], points[:,1], tri.simplices) plt.plot(points[:,0], points[:,1], 'o') plt.show()
输出量:
6xfqseft3#
我认为Delanuay给出了一个更接近船体的东西,在OP的图中,A没有连接到C,它连接到B,a又连接到C,给出了一个不同的形状。
一种解决方案是首先运行Delanuay,然后移除Angular 超过一定度数(例如90或100)的三角形。初步代码如下所示
from scipy.spatial import Delaunay points = [[101, 357], [198, 327], [316, 334], [ 58, 299], [162, 258], [217, 240], [310, 236], [153, 207], [257, 163]] points = np.array(points) tri = Delaunay(points,furthest_site=False) newsimp = [] for t in tri.simplices: A,B,C = points[t[0]],points[t[1]],points[t[2]] e1 = B-A; e2 = C-A num = np.dot(e1, e2) denom = np.linalg.norm(e1) * np.linalg.norm(e2) d1 = np.rad2deg(np.arccos(num/denom)) e1 = C-B; e2 = A-B num = np.dot(e1, e2) denom = np.linalg.norm(e1) * np.linalg.norm(e2) d2 = np.rad2deg(np.arccos(num/denom)) d3 = 180-d1-d2 degs = np.array([d1,d2,d3]) if np.any(degs > 110): continue newsimp.append(t) plt.triplot(points[:,0], points[:,1], newsimp)
这给出了上面看到的形状。对于更复杂的形状,
for t in tri.simplices: ... n1 = np.linalg.norm(e1); n2 = np.linalg.norm(e2) ... res.append([n1,n2,d1,d2,d3]) res = np.array(res) m = res[:,[0,1]].mean()*res[:,[0,1]].std() mask = np.any(res[:,[2,3,4]] > 110) & (res[:,0] < m) & (res[:,1] < m ) plt.triplot(points[:,0], points[:,1], tri.simplices[mask])
3条答案
按热度按时间vyswwuz21#
您可以使用scipy.spatial.Delaunay。以下是
下面是与您的输入类似的结果:
三角形存储在Delaunay对象的
simplices
属性中,该对象引用存储在points
属性中的坐标:如果要查找连接的顶点,则还有一个包含该信息的属性:
isr3a4wc2#
您可以尝试scipy.spatial.Delaunay。从该链接:
输出量:
6xfqseft3#
我认为Delanuay给出了一个更接近船体的东西,在OP的图中,A没有连接到C,它连接到B,a又连接到C,给出了一个不同的形状。
一种解决方案是首先运行Delanuay,然后移除Angular 超过一定度数(例如90或100)的三角形。初步代码如下所示
这给出了上面看到的形状。对于更复杂的形状,