Ответ 1
Кажется, нет никакого очевидного способа непосредственного получения результатов, за которыми вы после, независимо от того, какие параметры вы проходите. Не нужно слишком сложно вычислить себя, если вместо ConvexHull
вы используете Delaunay
(который также предоставляет большую часть информации о выпуклой оболочке).
def tetrahedron_volume(a, b, c, d):
return np.abs(np.einsum('ij,ij->i', a-d, np.cross(b-d, c-d))) / 6
from scipy.spatial import Delaunay
pts = np.random.rand(10, 3)
dt = Delaunay(pts)
tets = dt.points[dt.simplices]
vol = np.sum(tetrahedron_volume(tets[:, 0], tets[:, 1],
tets[:, 2], tets[:, 3]))
РЕДАКТИРОВАТЬ. В соответствии с комментариями более быстрыми способами получения объема выпуклой оболочки:
def convex_hull_volume(pts):
ch = ConvexHull(pts)
dt = Delaunay(pts[ch.vertices])
tets = dt.points[dt.simplices]
return np.sum(tetrahedron_volume(tets[:, 0], tets[:, 1],
tets[:, 2], tets[:, 3]))
def convex_hull_volume_bis(pts):
ch = ConvexHull(pts)
simplices = np.column_stack((np.repeat(ch.vertices[0], ch.nsimplex),
ch.simplices))
tets = ch.points[simplices]
return np.sum(tetrahedron_volume(tets[:, 0], tets[:, 1],
tets[:, 2], tets[:, 3]))
С некоторыми составленными данными второй метод, кажется, примерно в 2 раза быстрее, и числовая точность кажется очень хорошей (15 знаков после запятой!!!), хотя должно быть несколько более патологических случаев:
pts = np.random.rand(1000, 3)
In [26]: convex_hull_volume(pts)
Out[26]: 0.93522518081853867
In [27]: convex_hull_volume_bis(pts)
Out[27]: 0.93522518081853845
In [28]: %timeit convex_hull_volume(pts)
1000 loops, best of 3: 2.08 ms per loop
In [29]: %timeit convex_hull_volume_bis(pts)
1000 loops, best of 3: 1.08 ms per loop