【发布时间】:2013-07-30 09:22:46
【问题描述】:
【问题讨论】:
-
区域是如何定义的?它是一个任意的非凸区域吗?
-
@RobWatts 为简单起见,首先考虑一个没有任何孔的任意(非多边形)非凸区域。
标签: convex non-convex
【问题讨论】:
标签: convex non-convex
我写了an answer to this question on the Mathematics Stack Exchange,并附上了我使用概念验证实现创建的图像。用于此的方法可能适用于许多实际应用,因此我将在这里更详细地描述它。
选择你的形状,并使用多边形来近似它。识别内角 > 180° 的连续顶点的运行。对于每次这样的运行,迭代所有可能的切线。连线的切线是连接两个连续顶点的线,其中至少一个位于连线内。这意味着第一行由运行前的最后一个顶点和运行的第一个顶点定义。取这条线定义的向内半平面,将其与您的形状相交,然后计算面积并将其与目前找到的最佳解决方案进行比较。
在一种简单的方法中,您只需设置一个递归方案来尝试所有可能的行组合。这意味着时间复杂度为 O(nm),其中 n 是顶点数,m 是运行次数。在更精细的方法中,您可以利用这样一个事实,即可以独立于其他线选择不与形状内的任何其他线相交的线。对于在形状内部不相交的线组也是如此。某些行的选择将完全切断不同的运行,因此为该运行所做的选择变得无关紧要。因此,这里有很多聪明算法的潜力,这取决于您可以投入多少精力以及您需要什么性能。
如果您的输入是多边形,那么与非凸顶点接触的线不必与多边形的入边或出边重合,但可以在这两个限制之间任意旋转。对于这种情况,上述方法可能会产生非最佳解决方案。但既然你在评论中说我们可以假设“非多边形”形状,我认为这意味着“平滑”。在这种情况下,您在每个点都有一个明确定义的切线,并且每个切线都将合理地接近多边形近似的边缘。
与我最初的想法相反,上面的方法也适用于有孔的形状,因为凸孔的边界会导致形状本身的非凸运行。因此,该运行将确保您调查所有可能的方法来消除孔。非凸孔类似:相关运行将确保您也将它们切掉,而不会丢失任何凸解决方案。
应用于您的示例图像,该算法产生以下结果:
顶点的非凸面运行为红色,最佳线组为蓝色,生成的区域为绿色。这后面的多边形有 269 个顶点。该实现是用 Java 完成的,几乎不考虑性能,对所有可能的组合进行暴力递归搜索,以及一些适用于该输入数据但通常可能失败的假设。
【讨论】:
inflectionPoints 相关的几个地方。 pts 的循环解释假定没有漏洞。用于使用正方形近似半平面的任意长度 1200 可能需要调整。如果整体方向颠倒,findInflections 将需要一些符号更改。此列表可能不完整。为了性能,废弃 Java 并在 C++ 中重新启动。
c 和 C 之间的区别。