【发布时间】:2015-08-20 01:45:56
【问题描述】:
我有一个没有特定顺序的线段列表。
我想找到由线段形成的所有封闭空间(多边形)。有没有一种有效的算法或方法可以用来做到这一点?
下图说明了问题。给定黑色线段,如何检测绿色多边形?
【问题讨论】:
标签: c# algorithm graph polygon convex-hull
我有一个没有特定顺序的线段列表。
我想找到由线段形成的所有封闭空间(多边形)。有没有一种有效的算法或方法可以用来做到这一点?
下图说明了问题。给定黑色线段,如何检测绿色多边形?
【问题讨论】:
标签: c# algorithm graph polygon convex-hull
一种方法是按如下方式构建图表:
节点是边的交点
如果点 i 和 j 在节点 i 和 j 之间,则存在一条边同一条边
构建图表后:
在其上运行Connected Components Algorithm,并检查大小> 2的连接组件
在此类组件内的交点上运行convex hull 算法
编辑由于 FooBar 的出色观点而从原始修改。
【讨论】:
这确实是computational geometry中的经典问题。
您正在寻找您的细分中的arrangement 中的faces。
关于这个主题的讨论(太多)细节和源代码,有这个很棒的库:CGAL。
请注意,您必须决定要做什么,例如一个多边形内另一个多边形,许多多边形交织在一起,等等。
【讨论】:
Ami 的回答是正确方向的一个很好的指针,但以下是您可能需要了解的更详细的步骤:
获取线段列表并构建顶点集合。由于通过蛮力检查每个单独的线段是否与其他线段相交基本上是 N^2 操作,因此您可能需要构建一个四叉树并使用它来减少您正在执行的检查次数。如果 n 很小或者你有很多 cpu 时间要烧掉,那就暴力破解它,否则你需要聪明地进行碰撞检测。这是一个实现四叉树碰撞检测的库:https://github.com/hroger1030/SpatialTrees
使用您的节点和边列表,您可以构建图表。您可以将线节点和交叉点称为边缘,反之亦然,这无关紧要。重要的是你现在可以在图中找到所有循环中节点数 > 2 的循环。
我碰巧用c#写了一个Tarjan循环检测的实现:Tarjan cycle detection help C#。这可能是建议的连接组件算法的替代方案。
【讨论】: