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

时间:2008-09-17 14:04:46

标签: algorithm math geometry 2d gis

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

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

10 个答案:

答案 0 :(得分:10)

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

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

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

答案 1 :(得分:2)

这些家伙here声称已经开发了一种k近邻方法来确定一组点的凹壳,其行为“几乎线性地在点数上”。可悲的是,他们的论文似乎得到了很好的保护,你不得不问them

这是一个包含上述内容的good set of references,可能会让您找到更好的方法。

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

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

答案 4 :(得分:1)

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

  1. 创建一个集合N(“未包含”),并将集合中的所有点添加到N。
  2. 随机从N中选取3个点以形成初始多边形P.从N中删除它们。
  3. 使用some point-in-polygon algorithm并查看N中的点。对于N中的每个点,如果它现在由P包含,则将其从N中删除。一旦在N中找到仍未包含的点, P,继续执行步骤4.如果N变为空,则表示您已完成。
  4. 调用您找到的点A.找到P中最接近A的行,并在其中间添加A.
  5. 返回第3步
  6. 我认为只要它表现得足够好就会有效 - 对于你最初的3分,一个好的启发式可能会有所帮助。

    祝你好运!

答案 5 :(得分:1)

一个简单的解决方案是绕多边形的边缘走动。给定边界连接点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),因此您需要稍微对点名单进行排序。如果您根据城市的质心对点进行排序,则可以限制在每次迭代时需要考虑的点集。

答案 6 :(得分:1)

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

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

答案 7 :(得分:1)

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

答案 8 :(得分:0)

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

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

还需要事先快速检查一下很长的薄形状,然后决定使用NS或Ew。

答案 9 :(得分:0)

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

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

相关问题