多面体的德劳内三角剖分(Python)

4
我正在尝试在Python中获取一个多面体的德劳内三角剖分,以便我可以计算重心。我看到scipy.spatial中有一个德劳内函数,并且它适用于n维空间。问题是文档只显示了2D用法,并没有指示如何处理更高维度的情况。如果能将这个对象分解成数组可能就能解决我的问题,但我不知道该怎么做。
我遇到的问题是我不知道如何验证它是否正常工作,因为它输出一个对象。我在Google上找不到任何关于如何绘制多面体或如何使用scipy返回的这个对象的信息。
如果我执行:
import numpy as np
from scipy.spatial import Delaunay

points = np.array([[0,0,0],[1,0,0],[1,1,0],[1,0,1],[1,1,1],[0,1,0],[0,1,1],[0,0,1]])
Delaunay(points)

我希望能够获取这些四面体的坐标,以便计算多面体的重心。如果能绘制出这个分割后的多面体就更好了。我在MATLAB中发现可以使用一个名为trimesn的函数来完成此操作,但我在matplotlib中找到的函数似乎非常不同,并且其文档也不是很好。

from matplotlib.collections import TriMesh TriMesh.__doc__ 

u'\n      Class for the efficient drawing of a triangular mesh using\n   
Gouraud shading.\n\n    A triangular mesh is a
:class:`~matplotlib.tri.Triangulation`\n    object.\n    '

你不需要使用Delaunay三角剖分来计算重心。你可以计算适当权重的四面体重心之和。 - Joseph O'Rourke
我怎么得到四面体?在这种特殊情况下很简单,但对于任意六面体呢? - Steven Walton
我已经将我的评论扩展为答案。 - Joseph O'Rourke
2个回答

4
tess = Delaunay(pts)返回的是Delaunay类的对象。你可以通过tess.simplices检查四面体。它有不同的属性和方法。例如,在2D中,它可以绘制三角形剖分、凸包和Voronoi图。

关于最终四面体集合的可视化,我没有找到一个直接的方法,但我成功地编写了一个脚本。请参考下面的代码。

from __future__ import division
import numpy as np
from scipy.spatial import Delaunay
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
from itertools import combinations


def plot_tetra(tetra, pts, color="green", alpha=0.1, lc="k", lw=1):
    combs = combinations(tetra, 3)
    for comb in combs:
        X = pts[comb, 0]
        Y = pts[comb, 1]
        Z = pts[comb, 2]
        verts = [zip(X, Y, Z)]
        triangle = Poly3DCollection(verts, facecolors=color, alpha=0.1)
        lines = Line3DCollection(verts, colors=lc, linewidths=lw)
        ax.add_collection3d(triangle)
        ax.add_collection3d(lines)

pts = np.array([
            [0,0,0],
            [1,0,0],
            [1,1,0],
            [1,0,1],
            [1,1,1],
            [0,1,0],
            [0,1,1],
            [0,0,1]])
tess = Delaunay(pts)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for k, tetra in enumerate(tess.simplices):
    color = plt.cm.Accent(k/(tess.nsimplex - 1))
    plot_tetra(tetra, pts, color=color, alpha=0.1, lw=0.5, lc="k")
ax.scatter(pts[:, 0], pts[:, 1], pts[:, 2], c='k')
plt.savefig("Delaunay.png", dpi=600)
plt.show()

生成的图片如下所示:

enter image description here


1
抢先一步了!但比我想的好多了 :) - Andras Deak -- Слава Україні
谢谢,那真的很有帮助。 - Steven Walton

2
你不需要计算多面体的德劳内三角剖分来求得它的重心。 重心是由四面体重心的加权和组成,其中每个四面体的权重就是其体积。

你不需要将多面体划分为四面体。 首先,将多面体的面进行三角化,如将四边形划分为两个共面三角形等。 接下来,在空间中选择任意点p,比如原点。 现在,对于每个三角形面(a,b,c),计算四面体(p,a,b,c)的带符号体积。如果所有三角形都按逆时针方向定向,则此方法有效。 通过抵消,带符号体积负责处理一切问题。 使用带符号体积作为权重乘以四面体的重心。

四面体带符号体积的解释可在我的书籍《C语言计算几何》第1章中找到, “C语言计算几何”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接