it-swarm.cn

是否有一种有效的算法来生成2D凹壳?

从GIS文件(城市地图)获得一组(2D)点,我需要生成定义该地图(其边界)的“轮廓”的多边形。它的输入参数是点集和“最大边长”。然后它将输出相应的(可能是非凸的)多边形。

到目前为止,我发现的最佳解决方案是生成Delaunay三角形,然后移除长度超过最大边长的外边。在所有外边缘都短于此之后,我只需移除内部边缘并获得我想要的多边形。问题是,这非常耗时,我想知道是否有更好的方法。

59
Fabio Ceconello

这篇 论文讨论了 有效生成简单多边形,用于表征平面中一组点的形状 并提供算法。还有一个Java applet使用相同的算法 这里

2
Amirali

我们实验室的一名前学生在博士论文中使用了一些适用的技术。我相信其中一个被称为“alpha形状”,并在下面的文章中引用:

http://www.cis.rit.edu/people/faculty/kerekes/pdfs/AIPR_2007_Gurram.pdf

该论文提供了一些您可以遵循的进一步参考。

10
nsanders

对于其他人来说,答案可能仍然是有趣的:可以应用 行进方格算法的变化 ,应用(1)在凹形船体内,以及(2)然后开启(例如3)不同的 scale 我依赖于平均点密度。比例需要是彼此的int倍数,这样您就可以构建一个可用于高效采样的网格。这允许快速找到空样本=正方形,完全在点的“聚类/云”内的样本,以及在它们之间的那些样本。然后,后一类可以用于容易地确定代表凹壳的一部分的多义线。

在这种方法中,一切都是线性的,不需要三角测量,它不使用alpha形状,它与此处描述的商业/专利产品不同( http://www.concavehull.com/

2
monnoo

这些人 在这里 声称已经开发出k近邻方法来确定一组点的凹壳,其行为“几乎线性地在点数上”。可悲的是,他们的论文似乎得到了很好的保护,你必须要求 他们 为它。

这是一个 良好的参考集 包括上述内容,可能会引导您找到更好的方法。

2
Vinko Vrsalovic

Bing Maps V8交互式SDK在高级形状操作中具有凹壳选项。

https://www.bing.com/mapspreview/sdkrelease/mapcontrol/isdk/advancedshapeoperations?toWww=1&redig=D53FACBB1A00423195C53D841EA0D14E#JS

在ArcGIS 10.5.1中,3D Analyst扩展模块具有“最小边界体积”工具,其中包含凹形外壳,球体,包络或凸包的几何类型。它可以在任何许可级别使用。

这里有一个凹壳算法: https://github.com/mapbox/concaveman

1
Jaybird64

一个简单的解决方案是绕多边形的边缘走动。给定当前边缘连接点P0和P1的边界,边界P2上的下一个点将是具有最小可能A的点,其中

H01 = bearing from P0 to P1
H12 = bearing from P1 to P2
A = fmod( H12-H01+360, 360 )
|P2-P1| <= MaxEdgeLength

然后你设置

P0 <- P1
P1 <- P2

并重复,直到你回到你开始的地方。

这仍然是O(N ^ 2),因此您需要稍微对点名单进行排序。如果您根据城市的质心对点进行排序,则可以限制每次迭代时需要考虑的点集。

1
Mike F

您可以使用此插件在QGIS中执行此操作; https://github.com/detlevn/QGIS-ConcaveHull-Plugin

根据您需要与数据进行交互的方式,可能值得查看如何在此处完成。

1
Cameron

好问题!我根本没有试过这个,但我的第一个镜头就是这个迭代方法:

  1. 创建一个集合N(“未包含”),并将集合中的所有点添加到N.
  2. 随机从N中选取3个点以形成初始多边形P.从N中移除它们。
  3. 使用 一些多边形点算法 并查看N中的点。对于N中的每个点,如果它现在由P包含,则从N中删除它。一旦你在N中找到一个仍然是静止的点不包含在P中,继续执行步骤4.如果N变空,则表示已完成。
  4. 调用找到的点A.找到P中最接近A的行,并在其中间添加A.
  5. 回到第3步

我认为只要它表现得足够好就会起作用 - 对于你最初的3分,一个好的启发式可能会有所帮助。

祝好运!

1
Rob Dickerson

作为一个广泛采用的参考,PostGIS以凸包开始,然后将其嵌入,你可以在这里看到它。

https://github.com/postgis/postgis/blob/380583da73227ca1a52da0e0b3413b92ae69af9d/postgis/postgis.sql.in#L5819

0
Evan Carroll

快速近似解(对凸壳也很有用)是找到东西向的每个小元素的北和南边界。

根据您需要的详细程度,创建一个固定大小的上/下边界数组。对于每个点,计算它所在的E-W列,然后更新该列的上/下边界。处理完所有点后,您可以插入错过的列的上/下点。

同样值得事先快速检查一下很长的薄形状,然后决定是否使用NS或Ew。

0
Martin Beckett