一种解决简单(?)数组问题的算法

时间:2010-07-08 12:23:20

标签: algorithm arrays pseudocode

对于这个问题,速度非常重要。我画了一个很好的图像来更好地解释这个问题。该算法需要计算矩形边缘是否在画布的范围内继续,边缘是否与另一个矩形相交?

我们知道:

  1. 画布的大小
  2. 每个矩形的大小
  3. 每个矩形的位置
  4. 解决方案越快越好!我非常坚持这个,并不知道从哪里开始。

    alt text http://www.freeimagehosting.net/uploads/8a457f2925.gif

    干杯

6 个答案:

答案 0 :(得分:6)

只需为每个X轴和Y轴创建一组间隔。然后,对于每个新矩形,查看X轴或Y轴是否存在交叉间隔。 See here用于实现区间集的一种方法。

在第一个示例中,水平轴上设置的区间为{ [0-8], [0-8], [9-10] },垂直方向上设置的区间为{ [0-3], [4-6], [0-4] }

这只是一个草图,我在这里抽象了许多细节(例如,通常会有人问一个间隔集/树“,这个间隔与这个间隔重叠”,而不是“与这一个相交”,但没有什么不可行)。

修改

Please watch this related MIT lecture(它有点长,但绝对值得)。 即使您找到了更简单的解决方案(而不是实现增强的红黑树),也很了解这些事情背后的想法。

答案 1 :(得分:2)

彼此不平行的线将在某个点相交。计算每条线的斜率,然后确定它们不会与哪条线相交。

从那开始,然后让我们看看如何优化它。我不确定您的数据是如何表示的,我看不到您的图像。

使用slope是一个简单的相等检查,这可能意味着您可以利用对数据进行排序。实际上,您可能只需创建一组不同的斜率。您必须弄清楚如何表示数据,以便同一矩形的两个斜率不计算为相交。

编辑:等等......边缘到无穷大的两个矩形怎么不相交?矩形基本上是两条彼此垂直的线。这不应该意味着如果这些线延伸到无穷大,它总是与另一个相交吗?

答案 2 :(得分:1)

只要你没有提到你选择解决问题的语言,我就会使用某种伪代码

这个想法是,如果一切正常,那么沿着一个轴的矩形边的排序集合应该是一系列非重叠的间隔。

  1. 为所有矩形编号,为其指定个别ID
  2. 创建一个空的二叉树集合(btc)。这个集合应该有一个方法来插入一个整数节点与info btc :: insert(key,value)
  3. 对于所有矩形,请执行:
  4. 
    foreach rect in rects do
        btc.insert(rect.top, rect.id)
        btc.insert(rect.bottom, rect.id)
    
    1. 现在遍历btc(这会给你一个排序的顺序)
    2. 
      btc_item = btc.first()
      do
          id = btc_item.id
          btc_item = btc.next()
          if(id != btc_item.id)
          then report_invalid_placement(id, btc_item.id)
          btc_item = btc.next()
      while btc_item is valid
      

      5,7,8 - 对rect.left和rect.right坐标重复步骤2,3,4

答案 3 :(得分:1)

我喜欢这个问题。以下是我试图了解它:

如果可能: 从每个矩形创建一个多边形。将每条边视为必须剪裁的最大长度线。使用剪切算法检查天气是否与另一条线相交。例如,这一个:Line Clipping

但请记住:如果找到位于顶点位置的交点,则它是有效的交点。

答案 4 :(得分:1)

这是一个想法。不是使用(x, y, width, height)创建每个矩形,而是使用(x1, y1, x2, y2)对它们进行实例化,或者至少让它在给定宽度和高度的情况下解释这些值。

这样,您可以检查哪些矩形具有相似的xy值,并确保相应的矩形具有相同的辅助值。


示例:

您给出的矩形具有以下值:

  • Square 1:[0,0,8,3]
  • Square 3:[0,4,8,6]
  • Square 4:[9,0,10,4]

首先,我们将Square 1Square 3进行比较(无碰撞):

  • 比较x值
    • [0,8]到[0,8]这些完全一样,所以没有交叉。
  • 比较y值
    • [0,4]到[3,6]这些数字都不相似,所以它们不是一个因素

接下来,我们将Square 3Square 4(碰撞)进行比较:

  • 比较x值
    • [0,8]到[9,10]这些数字都不相似,所以它们不是一个因素
  • 比较y值
    • [4,6]到[0,4]矩形的数字共有4个,但是0!= 6,因此存在碰撞

据我们所知,我们知道会发生碰撞,因此该方法会结束,但我们可以更加清晰地评估Square 1Square 4

  • 比较x值
    • [0,8]到[9,10]这些数字都不相似,所以它们不是一个因素
  • 比较y值
    • [0,3]到[0,4]矩形的数字为0,但是3!= 4,因此存在碰撞

如果您需要任何额外的细节,请告诉我们。)

答案 5 :(得分:0)

嘿,将重叠间隔应答到极端,您只需确定沿x和y轴的所有不同间隔。对于每条切割线,沿着它将根据间隔的起始值切割的轴进行上限搜索。如果没有找到间隔或者间隔与线不相交,则它是有效线。

稍微棘手的部分是要意识到有效切割线不会沿着轴与矩形的边界相交,因此您可以将重叠间隔组合成单个间隔。您最终得到一个简单的排序数组(您填写O(n)时间)和O(log n)搜索每个切割线。