【问题标题】:How to uniformly fill a volume of a convexHull given by a list of 3d points?如何均匀填充由3d点列表给出的convexHull的体积?
【发布时间】:2020-03-19 05:31:30
【问题描述】:

我有一个由scipy.spatial.ConvexHull 生成的 3d 点列表给出的凸包。

我希望以某种有效的方式用 3d 点均匀地填充整个体积。

如果我有一种快速的方法来知道一个点是在凸包内部还是外部,我可能会以某种分辨率对每个体素进行矢量化处理,如果它在“内部”则返回其中心,或者如果该体素不返回任何内容它是“外面”。


示例:

对于 2d 点,例如 scipy 的 ConvexHull 示例,

我想计算在红线内均匀分布的点列表。

如何才能更有效地做到这一点?

【问题讨论】:

  • 您是否有权访问ConvexHull 对象本身或仅访问顶点?
  • @paul panzer 我有访问权限。
  • 然后您可以使用包含表面法线的.equations 属性来测试输入/输出。在我看来,您必须提供要在“同质”坐标中检查的点,或者用简单的英语将 1 附加到每个点的坐标。然后矩阵相乘并检查结果的列。全正列表示内部点。一个负坐标就足以把你放在外面,一个非负但不是严格正的列意味着你在表面的某个地方。
  • 或者反过来说,也就是消极的,我说积极的,反之亦然。
  • @PaulPanzer 你能显示代码吗?我不太明白你的意思

标签: python numpy scipy convex-hull


【解决方案1】:

这里是一些(未优化的)示例代码,演示了 .equations 属性的使用,其中包含凸包的表面法线。

import numpy as np
from scipy import spatial

## set up example ##
# create sample points
np.random.seed(17)
samples = np.random.uniform(-5,5,(100,2))
# pick convex subset
outline = samples[(samples**2).sum(1)<4]
outline = spatial.ConvexHull(outline)
# choose tolerance for detection of boundary points
eps = 1e-9

## classify ##
outside = (outline.equations@np.c_[samples, np.ones(len(samples))].T > eps).any(0)
inside = (outline.equations@np.c_[samples, np.ones(len(samples))].T < -eps).all(0)
boundary = ~(outside|inside)

## plot ##
import pylab
closed = np.tile(outline.points[outline.vertices],(2,1))
closed = closed[:len(closed)//2+1]
pylab.plot(*closed.T,'b')
pylab.plot(*samples[outside].T,'og')
pylab.plot(*samples[inside].T,'or')
pylab.plot(*samples[boundary].T,'oy')
pylab.show()

【讨论】:

  • 谢谢!不幸的是,我们仍在使用 python 2.7... 是否可以快速替换 @
  • @Gulzar 有matmuldot
  • 你能解释一下.c_的用法吗?我发现这部分不清楚,即使它最终对我有用。
  • @Gulzar c_ 是柱式堆垛机;这里它在samples的末尾添加了一列@
  • 它有效!然而......我注意到它会检查每一个点,每一个方程。我想知道是否有更快的方法。我能想到的最重要的事情是越过一个维度(比如x)并找到船体中的第一个和最后一个点。其他人都在,无需检查。搜索可以完成 o(nlogn)。有没有更快的方法,也许是一些聪明的单纯形法?
猜你喜欢
  • 1970-01-01
  • 2021-01-30
  • 2015-02-24
  • 1970-01-01
  • 1970-01-01
  • 2021-05-14
  • 1970-01-01
  • 2017-10-15
  • 2021-09-12
相关资源
最近更新 更多