寻找近似算法以找到区域中最大的清晰圆

时间:2015-06-22 16:04:26

标签: algorithm graphics computational-geometry

相关:Is there a simple algorithm for calculating the maximum inscribed circle into a convex polygon?

我正在编写一个图形程序,其目标是艺术而非数学。它使用几何图元(例如线段或小角度的弧)逐步构成图像。因此,它寻找开放区域以填充更多细节;随着可用的开放区域越来越小,细节越来越精细,因此它的分形很松散。

在给定的步骤中,为了决定接下来要做什么,我们想要找出:哪个是最大的圆形区域仍然没有现有的几何图元?

问题的一些限制

  • 不需要准确。一个足够接近的答案很好。
  • 不精确应该在保守的方面犯错:一个几乎是最大的圆圈是可以接受的,但是一个不太空的圆圈是不可接受的。
  • CPU效率是一个优先事项,因为它会经常被调用。
  • 该程序将在浏览器中运行,因此内存效率也是一个优先事项。
  • 我必须对细节水平设置一个限制,可能会受到内存空间的限制。
  • 我们可以跟踪已经以任何所需方式绘制的图元,例如空间索引。不需要这些的准确性;例如存储边界框而不是弧线就可以了。然而,我们拥有的精度越高越好,因为它将允许程序绘制到更高级别的细节。但是,鉴于基元的数量可以随细节水平呈指数级增长,我们希望存储过去的细节而不是与基元的数量线性增加。

总结优先顺序

  1. 内存效率
  2. CPU效率
  3. 精密
  4. P.S。

    我用圈子来表达这个问题,但如果它更容易找到最大的清晰黄金矩形(或金色椭圆),那也可以。

    P.P.S。

    这张图片让我了解了我想要实现的目标。这是一个卷须绘制程序的开始,在这个程序中,关于在哪里发芽卷须以及有多大的决定没有关于剩余的开放空间。但现在我们想知道,接下来哪里有吸引卷须的空间,有多大?那之后呢?

    tendrils drawn within a circle

3 个答案:

答案 0 :(得分:2)

一种非常有效的方法是将您的区域递归划分为矩形子区域,必要时将它们分开以将占用区域与未占用区域分开。然后你只需要跟踪每次最大的未占用区域。请参阅https://en.wikipedia.org/wiki/Quadtree - 但您无需拆分为正方形。

给定任何矩形,您可以在其中绘制一条线,以使该线两侧的至少一个矩形为黄色矩形。因此,您可以递归地在矩形内竖立分区,以便除分区形成的矩形之外的所有矩形都是黄金矩形,并且剩下的添加矩形非常小。你可以这样做来创建一个类似四叉树的结构,几乎所有留下的矩形都是金色矩形。

答案 1 :(得分:1)

这似乎是一种随机算法可能有用的情况。随机选择点数,拒绝并选择更多因为某些原因它们不合适的点数,然后找到您选择的最小距离到已包含的每个数字。具有最大分钟的随机点将是您的选择。

随着数字复杂性的增加,样本点的数量可能不得不增加。

可以通过检查附近的好选择点来改进随机算法。继续检查邻居,直到不再可能改进为止。

答案 2 :(得分:1)

这是一种使用固定内存量和每次更新时间的简单方法,无论您使用多少个绘图基元。需要多少内存(以及每次更新的时间)可以根据"分辨率的高低来控制。你需要:

  1. 将空间划分为点网格。我们将维护一个2D数组d [],它记录从网格点(x,y)到条目d [x,y]中任何已经绘制的基元的最小距离。最初,将此数组中的每个元素设置为无穷大(或一些巨大的数字)。
  2. 每当你绘制一些图元时,迭代所有网格点(x,y),计算从(x,y)到刚刚绘制的图元的最小距离(或对它的一些保守近似)。例如,如果刚刚绘制的图元是以(p,q)为中心的半径r的圆,那么该距离将是sqrt((x-p)^ 2 +(y-q)^ 2)-r。然后使用这个新的距离值更新d [x,y],如果它小于其当前值
  3. 可以绘制最大圆而不接触任何已经绘制的图元的网格点是距离目前为止绘制的任何图元最远的网格点。要找到它,只需扫描d []找到它的最大值,并记下相应的索引(x,y)。 d [x,y]将是您可以安全用于此圆圈的最大半径。
  4. 根据需要重复步骤2和3。

    有几点:

    • 对于具有区域的图元,您可以将0或负值分配给对应于图元内的网格点的所有d [x,y]。
    • 对于任何凸基元,您通常可以通过扫描行(或列)"向外"来避免更新大多数d []数组。从刚刚绘制的图元边界开始:从当前网格点到图元的距离永远不会减小,所以如果这个距离变得大于d []中的先前最大值,那么我们知道我们可以停止扫描这个因为没有我们在其上计算的距离值可能小于它上的现有距离。