简体   繁体   English

将数组中的所有矩形相互合并

[英]Merge all rectangles in an array with each other

I have an array of rectangles and I want to merge all overlapping and adjacent rectangles into each other.我有一个矩形数组,我想将所有重叠和相邻的矩形合并到一起。 The final array should have no overlapping or adjacent rectangles.最终数组不应有重叠或相邻的矩形。 I tried doing the below code but some rectangles are still left over.我尝试执行以下代码,但仍然遗留了一些矩形。

func combine_boxes(boxes: Array) -> void:
    var merged := true
    while merged:
        merged = combine_all_overlapping_box(boxes)


func combine_all_overlapping_box(boxes: Array) -> bool:
    var box: Rect2 = boxes[0]
    # Remove our box
    boxes.remove(0)
    # Start from the back of the the array so removals are easier and don't invalidate the index
    var merged := false
    for j in range(boxes.size()-1, -1, -1):
        var collider: Rect2 = boxes[j]
        if overlap_adjacent(box, collider):
            box = box.merge(collider)
            # Remove collider box
            boxes.remove(j)
            merged = true
    # Either add the merge box in, or the unaltered box we remove at the start
    boxes.append(box)
    return merged

This what I have been able to come up with:这是我能够想出的:

func combine_rects(rects: Array) -> Array:
    var result := rects.duplicate()
    var merged := true
    while merged:
        merged = false
        rects = result
        result = []
        while rects.size() > 0:
            var current_rect:Rect2 = rects.pop_back()
            for index in for index in range(rects.size() - 1, -1, -1):
                var other_rect:Rect2 = rects[index]
                if current_rect.intersects(other_rect, true):
                    merged = true
                    current_rect = current_rect.merge(other_rect)
                    rects.remove(index)

            result.append(current_rect)

    return result

Let us look at the inner loop first:让我们先看看内部循环:

var current_rect:Rect2 = rects.pop_back()
for index in for index in range(rects.size() - 1, -1, -1):
    var other_rect:Rect2 = rects[index]
    if current_rect.intersects(other_rect, true):
        merged = true
        current_rect = current_rect.merge(other_rect)
        rects.remove(index)

result.append(current_rect)

As you can see I remove an element from rects and store it in current_rect .如您所见,我从rects中删除了一个元素并将其存储在current_rect中。 Then iterate over the rest of the elements, comparing it with them.然后遍历 rest 个元素,将其与它们进行比较。 I use intersects with true as second argument so it also considers adjacent rects as intersecting… If they intersect, I merge them.我使用intersects with true作为第二个参数,因此它也将相邻的矩形视为相交……如果它们相交,我将它们合并。 And also remove the other element with rects.remove(index) … I iterate backwards so I don't have to adjust the index .并且还删除了rects.remove(index)的另一个元素……我向后迭代,所以我不必调整index

Since I set the current_rect with the result of the merge ( current_rect = current_rect.merge(other_rect) ), I can continue merging more rects into it in the same loop.因为我用合并的结果设置了current_rect ( current_rect = current_rect.merge(other_rect) ),所以我可以在同一个循环中继续合并更多的 rect。

Finally I add whatever I ended up with to the result .最后,我将最终结果添加到result中。

If we look at the mid loop, we see that I do this until I exhaust rects :如果我们看一下中间循环,我们会看到我一直这样做,直到我用尽rects

while rects.size() > 0:
    var current_rect:Rect2 = rects.pop_back()
    for index in for index in range(rects.size() - 1, -1, -1):
        var other_rect:Rect2 = rects[index]
        if current_rect.intersects(other_rect):
            merged = true
            current_rect = current_rect.merge(other_rect)
            rects.remove(index)

    result.append(current_rect)

Since I only remove from rects (either by pop_back or by remove ) it must eventually be empty and the loop ends.由于我只从rects中删除(通过pop_back或通过remove )它最终必须为空并且循环结束。

Now look at the broader picture:现在看看更广泛的图景:

func combine_rects(rects: Array) -> Array:
    var result := rects.duplicate()
    var merged := true
    while merged:
        merged = false
        rects = result
        result = []
        while rects.size() > 0:
            var current_rect:Rect2 = rects.pop_back()
            for index in for index in range(rects.size() - 1, -1, -1):
                var other_rect:Rect2 = rects[index]
                if current_rect.intersects(other_rect):
                    merged = true
                    current_rect = current_rect.merge(other_rect)
                    rects.remove(index)

            result.append(current_rect)

    return result

We will continue looping as long as we merged something.只要我们合并了一些东西,我们就会继续循环。 The merged variable keeps track of that. merged变量会跟踪它。 I set it to true so the flow of execution enters the loop (the alternative would have been to make an infinite loop while true and use break ).我将其设置为true以便执行流程进入循环(替代方案是while true进行无限循环并使用break )。

For the loop we need to make sure merged starts false , and result is empty.对于循环,我们需要确保merged开始时为false ,并且result为空。 So we do that.所以我们这样做。 But also, we want to iterate over the results of the past iteration.而且,我们想要迭代过去迭代的结果。 Which is why I set rects = result .这就是我设置rects = result的原因。 And that means that I need the starting rects in result .这意味着我需要result中的起始rects I took the opportunity to work on a copy ( var result:= rects.duplicate() ).我借此机会制作了一份副本( var result:= rects.duplicate() )。

You should be able to use it like this:你应该能够像这样使用它:

boxes = combine_rects(boxes)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 javascript-如何将数组中的每个元素与其他数组中的其他元素合并? - javascript - How to merge each element in array with other elements in different array? 将不同的PHP数组值相互合并并按时间排序 - Merge different PHP array values into each other and sort by time 查找二维数组中所有矩形的坐标 - Find the coordinates of all rectangles in a 2D array 如何检查所有可能的数组矩形的总和 - How to check sums of all possible rectangles of array 将数组中的每个元素乘以同一数组中的所有其他元素 - Multiply each element in array by all other elements in same array NodeJS:通过异步过程将数组的每个元素与所有其他元素进行比较? - NodeJS: Comparing each element of an array with all other elements with an async process? 重新排列一个数组,让所有元素在 Java 中彼此相邻 - Rearrange an array to have all elements next to each other in Java 在 Swift 中相互检查数组中的所有元素 - Checking all elements in an array in Swift against each other 检测 JavaScript 随机数数组是否都是彼此的倍数? - Detect if JavaScript array of random numbers are all multiples of each other? 如何比较数组中的3个值,使“不”或“全部”彼此相等? - How can I compare 3 values in an array to “not” or “all” equal each other?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM