用于将具有大小/位置的对象的平面列表转换为树的算法?

时间:2012-03-05 20:20:12

标签: algorithm

我有一个像这样的对象列表:

[
  Rectangle(20, 30, 100, 200), // x, y, width, height
  Rectangle(50, 40, 50, 50),
  Text(60, 50, 'Text')
]

为了这个例子,第一个Rectangle是最底部的对象,Text是最顶层的。根据位置/大小,第二个Rectangle应该是第一个Rectangle的子元素,因为它完全包含在第一个和顶部。由于同样的原因,文本对象应该是第二个Rectangle的子对象。

我正在寻找讨论或指向算法的一般指针来有效地执行此操作。我正在建立自己的,但我可能会缺少一些聪明的东西。

编辑:这是我在coffeescript中的实现:

obj = 
  _isParent: (parent, child) ->
    pb = parent.getBounds() # this returns a rectangle
    return pb.contains(child.getBounds())

  generateHiearchy: (object, index, objects, cache) ->
    return cache[object._id] if cache[object._id]

    exObject = new Node(object)
    cache[object._id] = exObject

    for i in [index+1...objects.length]
      potentialParent = objects[i]
      if @_isParent(potentialParent, object)
        exParent = @generateHiearchy(potentialParent, i, objects, cache)
        exParent.addChild(exObject)
        break

    exObject

  generateTree: (objects) ->
    return [] unless objects and _.size(objects)

    cache = {}
    objects = @sort(objects)

    for i in [0...objects.length]
      object = objects[i]
      exobj = @generateHiearchy(object, i, objects, cache)

    (val for k, val of cache when not val.parent)

基本上,我对它进行排序,使得最顶层的是阵列头,然后走数组。在每次迭代中,我从当前节点一直递归到层次结构的顶部,沿途缓存节点。

1 个答案:

答案 0 :(得分:3)

您可能需要查看R-trees。此数据结构将矩形保持在树层次结构中。基本上,如果矩形节点R1具有子节点矩形R2,则意味着R2包含在R1中。看看维基百科上的illustration,这是非常不言自明的。

要根据需要定制此数据结构,您可以找到一种将Text对象表示为Rectangle(或与R-tree兼容的其他多维对象)的方法。

找到一个开源实现应该很容易。希望这符合您的需求!