How to get uniformly distributed points in convex hull?

流过昼夜 提交于 2020-06-13 00:10:20

问题


Given a set of points,

points = np.random.randn(...) # n 3d points

I would like to uniformly fill the volume defined by the convex hull in which they lie by a list (np.array of shape nx3) of 3d points.

I can get the convex hull by

hull = scipy.spatial.ConvexHull(points)

What would be the fastest way to get a list of points that uniformly fills this hull's volume?


回答1:


1) Find delaunay simplices of the hull

2) randomly sample the simplices based on their area

3) for each simplex, find uniform distribution of sampled points using dirichelet distribution

4) multiply the distributions with the simplices to find final points.

from scipy.spatial import ConvexHull, Delaunay
import numpy as np
from numpy.linalg import det
from scipy.stats import dirichlet


def dist_in_hull(points, n):
    dims = points.shape[-1]
    hull = points[ConvexHull(points).vertices]
    deln = points[Delaunay(hull).simplices]

    vols = np.abs(det(deln[:, :dims, :] - deln[:, dims:, :])) / np.math.factorial(dims)    
    sample = np.random.choice(len(vols), size = n, p = vols / vols.sum())

    return np.einsum('ijk, ij -> ik', deln[sample], dirichlet.rvs([1]*(dims + 1), size = n))

EDIT: functionalized and extended to higher dimensions (Warning: ConvexHull only works up to 9D)




回答2:


Draw points uniformly in the bounding box and reject those that aren't inside the hull. (As the hull is convex, this can be done in linear time O(F) without preprocessing, and logarithmic time O(log F) after preprocessing, projecting the faces to a plane and considering a planar subdivision).



来源:https://stackoverflow.com/questions/59073952/how-to-get-uniformly-distributed-points-in-convex-hull

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!