通过球体的联合近似实体

时间:2015-05-14 17:29:43

标签: computational-geometry mathematical-optimization approximation convex

我有一个3D实体,表示为一组多面体凸壳的联合。 (或者单个凸起,如果这样可以使事情变得更容易。)我想将该实体近似为一组球体的并集,以最小化集合中球体的数量和近似中的误差。 (后一个目标是刻意模糊的:任何合理的误差度量都可以。同样,目标组合的方式在空中;要么球体的数量或误差度量可能受到限制,要么两者的某些功能可以最小化。我不想把自己指定到一个角落。)

近似值不需要完全包含完全包含在原始集合中。每个球体可以具有任意半径。

这感觉就像NP完全的那种问题,并且在任何情况下使用精确方法都不太可行,所以我假设解决方案在于随机优化领域。感觉k-means的某些变体可能适合(将未覆盖的位置分配给它们最近的球体,并精炼球体以覆盖其中的一些),但我不确定如何处理多重覆盖的位置,或者如何找到局部的,不一定是覆盖 - 即使对于单个球体也是最佳的。此外,对于迭代方法,效率很重要,并且执行3D布尔操作 不会有效。

4 个答案:

答案 0 :(得分:7)

问题并不简单,但之前已经研究过。中心概念 是medial axis,可以是 被无限的球联合视为一个物体的表现。 解决您问题的关键文章是:

  

“力量外壳,球的联合和内轴转换。”   Nina Amenta,Sunghee Choi,Ravi Krishna Kolluri。 计算几何。   第19卷,第2-3期,2001年7月,第127-153页。 (Journal link。)

<小时/> FootBalls ShellBalls
(图片来源:From Point Clouds to Power Crusts。)

第二篇论文是

  

Cazals,Frédéric,et al。 “用于球的集合的贪婪几何算法,应用于几何近似和分子粗粒化。” 计算机图形论坛。卷。 33. No. 6. 2014.(PDF download。)

其第一句是“选择最接近3D物体的球是一个非平凡的问题。”! 它们的主要应用是分子模型,这可能是远远不够的 从你的兴趣。

答案 1 :(得分:3)

嗯,到目前为止,我最好的想法是支持向量机。将对象转变为对象表面内和表面上的一大堆(可能是均匀间隔的)点。使用线性内核训练SVDD模型(有关SVDD实现,请参阅libsvm)。然后,模型的决策函数表示由模型(和rho)的支持向量定义的隐式表面。降低成本将为您提供更多的支持向量,将其提高可以减少您的需求。

不幸的是,SVM的本质是这样的,附近的支持向量覆盖的区域,呃,'blob'在一起,有点像这样:

enter image description here

(对不起,我对SVM的直觉完全是几何/视觉的。)

现在,你没有漂亮的清脆球体,但是(大手挥手!)希望算法选择一个有用的球体中心分布。

最后,你可以编写一个函数来计算误差,作为所有这些点上的球体中心的半径函数。然后将其输入非线性优化器并告诉它最小化。的Bam

如果你愿意为它投入更多的CPU能力,你可以在那个之上运行另一层错误最小化,这会重新运行整个上述过程以获得不同的支持向量成本,试图最小化错误和成本。 (也许是error/cost。)

答案 2 :(得分:1)

这就是我想出的。这种方法更像是一种迭代的3D布尔操作,因此它可能不是您正在寻找的。表面似乎更难,所以我专注于此。

概述

基本上在形状内添加球体,使球体的覆盖范围最大化。我们将球体转换为带符号字节值的3D数组。这些值是点,并将与球体吞噬。我们在对象内部一次添加一个球体,然后在不同的方向上生长/缩小它,以便进入&#34;吃掉#34;尽可能多的积分。目标是为每个球体提供尽可能多的点数。通过对球体区域中的点求和来获得积分。通过添加每个球体,我们计算然后计算所使用的区域,并将Array值设置为0.

  (A)       (B) ZZZZZZ   (C) ZZZZZZ   (D) ZZZZZZ   (E) ZZZZZZ   (F) ZZZZZZ   
     /\         ZX33XZ       ZX33XZ       ZX33XZ       ZX33XZ       ZX33XZ   
    /  \       ZX3223XZ     ZX3223XZ     ZX##23XZ     ZX  ##XZ     ZX    XZ  
   /    \     ZX321123XZ   ZX321123XZ   ZX####23XZ   ZX  ####XZ   ZX      XZ 
  |      |   ZX32111123XZ ZX32111123XZ ZX######23XZ ZX  ######XZ ZX        XZ
  |      |   ZX32111133XZ ZX32111133XZ ZX######23XZ ZX  ######XZ ZX        XZ
  |      |   ZX32222223XZ ZX##222223XZ ZX3####223XZ ZX3  ####3XZ ZX3     ##XZ
  |------|   ZX33333333XZ ZX##333333XZ ZX33##3333XZ ZX33  ##33XZ ZX33    ##XZ
   X= -1     ZXXXXXXXXXXZ ZXXXXXXXXXXZ ZXXXXXXXXXXZ ZXXXXXXXXXXZ ZXXXXXXXXXXZ
   Y= -2     ZZZZZZZZZZZZ ZZZZZZZZZZZZ ZZZZZZZZZZZZ ZZZZZZZZZZZZ ZZZZZZZZZZZZ

(A)我们想要填充的形状。 (2D在这里使用但3D会相似)

(B)在3D网格点中转换形状。 Surface获得最大数量,当你工作到中心时,数字以低正数结算(如1);形状之外得到负数;深的内部得到1

(C)添加一个小球体。 (我们会成长)

(D)展开球体,直到我们吞噬最大点数

(E)添加下一个球体并使其长大。

(F)添加另一个球体。这个很小。

过程

5)首先将形状分解为3D块分辨率。

10)然后给出最多的&#34;积分&#34;到了表面周围的块。当您向内或向外移动时,实际接触表面和较低点的块的高点。当你向外走时,积分应该很快变成负值,因为这会阻止突出的球体。当你从地面向内移动时,点应该稳定在1,这样中心区域就是全部。可以通过不同方式设置这些点以产生不同的结果。

15)在球体外部的形状内边缘找到一个位置。虽然不需要靠近边缘,但它确实最小化了搜索区域。如果找不到位置goto 80.如果找不到附近的位置

20)在未覆盖的形状内绘制半径为零的球体

25)向上/向下移动球体直到点最大化(模拟退火)

26)将球体移入/移出直到点最大化

27)向左/向右移动球体直到点最大化

28)向上/向下移动球体顶部直到点最大化(模拟退火/爬山)

29)向上/向下移动球体的底部直到点最大化

30)将球体的左侧移入/移出,直到点最大化

31)将球体的右侧移入/移出,直到点最大化

32)将球体的前部移入/移出,直到点最大化

50)如果25-32有任何变化,则重复(转到25)

70)从最后添加的球体中减去点数。对于内部值(正数),将所有值设置为零,不调整外部值(负数)。转到15。

80)(可选)填写内部空白。基本上访问每个元素以确保它小于或等于0.如果为正,则使用该元素转到20。否则,如果没有找到则转到85.注意:所有外部值都应为负值,并且球体内的所有内部值都应为0.

85)完成

备注

  • 由于存在值网格,因此1000x1000x1000工作空间将耗尽1GB。
  • 不是一个确切的解决方案
  • 可以为更高分辨率进行大量计算。
  • 为了提高效率,较小的球体可以预先记录其像素范围,这样就不需要为每次迭代计算球体。
  • 可以首先完成较低分辨率(即500x500x500)的版本,然后可以将球体的位置和大小应用于更大的1000x1000x1000。对于非常大的形状,也可以解决子部分。

答案 3 :(得分:0)

一个好的开始是开发一个算法:

1)找到内切球体的最大半径。

2)然后考虑减去体积

3)用多面体近似减去体积。

4)将多面体细分为更小(更精细)的多面体。

5)重做步骤1.

可能会有一些变化,但它似乎回答了你的问题。正如您所看到的,误差函数随着球体数量的增加而减少,因此您无法将两者最小化:这是一种权衡。但你可以修复一个并尝试优化另一个,例如将误差函数固定为可接受的公差,并最小化要执行的球体数量,反之亦然。