我有一个3D实体,表示为一组多面体凸壳的联合。 (或者单个凸起,如果这样可以使事情变得更容易。)我想将该实体近似为一组球体的并集,以最小化集合中球体的数量和近似中的误差。 (后一个目标是刻意模糊的:任何合理的误差度量都可以。同样,目标组合的方式在空中;要么球体的数量或误差度量可能受到限制,要么两者的某些功能可以最小化。我不想把自己指定到一个角落。)
近似值不需要完全包含或完全包含在原始集合中。每个球体可以具有任意半径。
这感觉就像NP完全的那种问题,并且在任何情况下使用精确方法都不太可行,所以我假设解决方案在于随机优化领域。感觉k-means的某些变体可能适合(将未覆盖的位置分配给它们最近的球体,并精炼球体以覆盖其中的一些),但我不确定如何处理多重覆盖的位置,或者如何找到局部的,不一定是覆盖 - 即使对于单个球体也是最佳的。此外,对于迭代方法,效率很重要,并且执行3D布尔操作 不会有效。
答案 0 :(得分:7)
问题并不简单,但之前已经研究过。中心概念 是medial axis,可以是 被无限的球联合视为一个物体的表现。 解决您问题的关键文章是:
“力量外壳,球的联合和内轴转换。” Nina Amenta,Sunghee Choi,Ravi Krishna Kolluri。 计算几何。 第19卷,第2-3期,2001年7月,第127-153页。 (Journal link。)
<小时/>
第二篇论文是
Cazals,Frédéric,et al。 “用于球的集合的贪婪几何算法,应用于几何近似和分子粗粒化。” 计算机图形论坛。卷。 33. No. 6. 2014.(PDF download。)
其第一句是“选择最接近3D物体的球是一个非平凡的问题。”! 它们的主要应用是分子模型,这可能是远远不够的 从你的兴趣。
答案 1 :(得分:3)
不幸的是,SVM的本质是这样的,附近的支持向量覆盖的区域,呃,'blob'在一起,有点像这样:
(对不起,我对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)完成
答案 3 :(得分:0)
一个好的开始是开发一个算法:
1)找到内切球体的最大半径。
2)然后考虑减去体积
3)用多面体近似减去体积。
4)将多面体细分为更小(更精细)的多面体。
5)重做步骤1.
可能会有一些变化,但它似乎回答了你的问题。正如您所看到的,误差函数随着球体数量的增加而减少,因此您无法将两者最小化:这是一种权衡。但你可以修复一个并尝试优化另一个,例如将误差函数固定为可接受的公差,并最小化要执行的球体数量,反之亦然。