【问题标题】:Random Rectangles without Overlapping some Pixels不重叠某些像素的随机矩形
【发布时间】:2022-01-19 18:08:25
【问题描述】:

我想生成随机矩形。这是一项相当容易的任务。问题是我需要它们不与任何这些黑点重叠:


倒置以便于观察:

现在我可以告诉它忽略它生成的任何矩形,如果它与任何黑点重叠,但随着点密度的增加,它会达到bogosort 的低效率水平。有没有更有效的方法来做到这一点?

【问题讨论】:

  • 也许您可以随着点密度的增加而减小矩形大小。
  • 我试过了,虽然它改进了一些东西,但它并没有解决核心问题。
  • 矩形可以相互重叠吗?
  • 是的,他们可以。虽然不是问题的一部分,但在我的例子中,我放置了一个矩形,其中一部分创建了更多点,但其余部分可以重叠。

标签: python algorithm image optimization random


【解决方案1】:

您可以使用多个随机生成的四叉树来生成不包含任何点的轴对齐边界框列表,然后对于每个矩形,从列表中随机选择一个 AABB,然后在 AABB 内随机生成一个矩形.

您不需要保留四叉树结构,因为您只对叶节点(AABB)感兴趣。从包含整个 2D 空间的 AABB 开始,并编写一个接受 AABB 和点列表的递归函数。创建一个空的 AABB 列表,然后调用具有顶级边界框和点列表的函数。

在函数内部,随机选择一个点作为分割线,随机选择一个方向(水平或垂直)或水平和垂直交替。创建两个点列表,由拆分点的 X 或 Y 值上方和下方的点组成,并通过使用该点拆分 AABB 参数创建两个 AABB,然后递归调用该函数两次。如果使用空点列表调用函数,则将 AABB 添加到列表中并停止递归。

如果您从顶层多次调用它,您的列表中将有一大堆重叠的 AABB(假设分裂点是随机选择的),因此在随机生成中不会有任何明显的伪影。然后,您可以随意生成任意数量的矩形。

点数的设置将是 O(N log N)(在平均情况下),随机矩形生成将是 O(1)。

为了使分布更均匀,您可以计算列表中每个 AABB 的面积,并根据其大小对随机选择它的概率进行加权。如果您使用二叉搜索树将原始随机数映射到加权 AABB,它会使您的随机生成 O(log N)

【讨论】:

    【解决方案2】:
    1. 生成随机线段(不通过任何点)(附图上的绿线)
    2. 查找到矩形每边最近点的距离(红线)
    3. 在属于矩形边的红线上随机选择两个点(黄点)

    【讨论】:

    • 这很聪明,但它只是将问题沿着链条向下移动到找到线,你能提供一个好的方法吗?虽然这对于更高的密度来说是一个相当大的改进。
    • 您可以进一步扩展相同的想法,即选择一个随机点并检查在到达某个点之前您可以在每一侧走多远(尽管使用直线比使用矩形的可能性要小得多)和然后选择这些边界之间的初始段。
    【解决方案3】:
    1. 选择一个随机的白点。

    2. 找到最近的黑点。这将是一个圆的半径

    3. 创建一个以随机点为中心的圆。

    4. 在圆上选择 2 个点。找到他们通过圆心的对立点,从4个点画出矩形。

    附:只要确保这两个点不是圆的直径...

    【讨论】:

    • 虽然这完全符合我的目的,但我会注意到这并不是真正的随机。我不是 100% 确定,但我认为选择圆内而不是圆内的点会使它再次随机化。这也将修复 PS。
    【解决方案4】:

    这是我的想法,与其他人提出的想法略有不同。算法如下:

    1. 为点的 x 和 y 创建 2 个数组。复制 x 和 ys 并对数组进行递增排序。
    2. 创建一个随机 x 和随机 y。这将是矩形的左上角。我们称他们为x1y1
    3. 在 x 数组中进行二分搜索,寻找最小的 x,使得 x >= x1
    4. 在 y 数组中进行二分搜索,找到最大的 y,使得 y <= y1
      • if x1 == x or y1 == y: go to step 2 注意:我们不能展开来创建一个矩形。
    5. 在您在步骤 3 中找到的 x1 and the right bound x 之间创建一个随机 x,两端互斥。叫它x2
    6. 在您在步骤 4 中找到的 y2 and the lower bound y 之间创建一个随机 y,两端互斥。叫它y2
    7. (x1, y1)(x2, y2) 保存为矩形的左上角和右下角。
    8. 从第 2 步开始重复。

    该算法在准备阶段具有O(n * log n) 的初始时间复杂度和O(n) 的空间复杂度,其中n 是给定点的数量。对于二分搜索,每个矩形创建的时间复杂度为O(log n)。我假设矩形的左上角和一个点发生碰撞的概率很低,我们可以忽略它。

    如果您为这些点选择了正确的数据结构(如排序地图、排序列表或类似内容,具体取决于特定语言中的名称),此方法还允许您以对数时间更新这些点。

    【讨论】:

      猜你喜欢
      • 2018-09-14
      • 1970-01-01
      • 2011-01-15
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 2020-07-13
      • 1970-01-01
      • 2018-11-02
      相关资源
      最近更新 更多