【问题标题】:find the maximum convex area找到最大凸面积
【发布时间】:2013-07-30 09:22:46
【问题描述】:

我的问题和Plow's Question很相似;但有这个区别:

如何找到可以容纳在非凸区域内的最大凸区域?

例如,考虑这个非凸区域:

任何想法或解决方案将不胜感激,谢谢。

【问题讨论】:

  • 区域是如何定义的?它是一个任意的非凸区域吗?
  • @RobWatts 为简单起见,首先考虑一个没有任何孔的任意(非多边形)非凸区域。

标签: convex non-convex


【解决方案1】:

我写了an answer to this question on the Mathematics Stack Exchange,并附上了我使用概念验证实现创建的图像。用于此的方法可能适用于许多实际应用,因此我将在这里更详细地描述它。

选择你的形状,并使用多边形来近似它。识别内角 > 180° 的连续顶点的运行。对于每次这样的运行,迭代所有可能的切线。连线的切线是连接两个连续顶点的线,其中至少一个位于连线内。这意味着第一行由运行前的最后一个顶点和运行的第一个顶点定义。取这条线定义的向内半平面,将其与您的形状相交,然后计算面积并将其与目前找到的最佳解决方案进行比较。

在一种简单的方法中,您只需设置一个递归方案来尝试所有可能的行组合。这意味着时间复杂度为 O(nm),其中 n 是顶点数,m 是运行次数。在更精细的方法中,您可以利用这样一个事实,即可以独立于其他线选择不与形状内的任何其他线相交的线。对于在形状内部不相交的线组也是如此。某些行的选择将完全切断不同的运行,因此为该运行所做的选择变得无关紧要。因此,这里有很多聪明算法的潜力,这取决于您可以投入多少精力以及您需要什么性能。

如果您的输入是多边形,那么与非凸顶点接触的线不必与多边形的入边或出边重合,但可以在这两个限制之间任意旋转。对于这种情况,上述方法可能会产生非最佳解决方案。但既然你在评论中说我们可以假设“非多边形”形状,我认为这意味着“平滑”。在这种情况下,您在每个点都有一个明确定义的切线,并且每个切线都将合理地接近多边形近似的边缘。

与我最初的想法相反,上面的方法也适用于有孔的形状,因为凸孔的边界会导致形状本身的非凸运行。因此,该运行将确保您调查所有可能的方法来消除孔。非凸孔类似:相关运行将确保您也将它们切掉,而不会丢失任何凸解决方案。

应用于您的示例图像,该算法产生以下结果:

顶点的非凸面运行为红色,最佳线组为蓝色,生成的区域为绿色。这后面的多边形有 269 个顶点。该实现是用 Java 完成的,几乎不考虑性能,对所有可能的组合进行暴力递归搜索,以及一些适用于该输入数据但通常可能失败的假设。

【讨论】:

  • 如何将程序扩展到一般情况? (如果我更改代码以适用于其他地区;应该更改哪些部分?-我对 java 编程很陌生!我写了一封信并寄给你)
  • @ZiaPandorra:Java 是我的选择,因为它可以开箱即用地进行区域交叉。我将列出一些我知道的隐含假设。多边形的起点将在一个凸区域内,假设在与inflectionPoints 相关的几个地方。 pts 的循环解释假定没有漏洞。用于使用正方形近似半平面的任意长度 1200 可能需要调整。如果整体方向颠倒,findInflections 将需要一些符号更改。此列表可能不完整。为了性能,废弃 Java 并在 C++ 中重新启动。
  • 哦!废弃java代码对你来说很容易,但对我来说却不是!那么坐标呢?你是一一插入的吗?!
  • @Zia:代码太丑了,不能复制和使用。将其视为解释该做什么的一种方式,尝试理解该解释并以您感到宾至如归的语言遵循它。对于坐标:我拍摄了您的图像,将其导入到 inkscape 中,将其追踪到表示黑色轮廓的填充区域,获取其内部边界,获取其 SVG 描述,使用 Emacs 宏对其进行转换,最后调整一些小部分手动,例如应用图层的全局 y 偏移量。如果您了解 SVG,您可能会识别路径数据中 cC 之间的区别。
猜你喜欢
  • 2017-12-04
  • 2015-02-08
  • 2016-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 2013-12-31
相关资源
最近更新 更多