簡體   English   中英

將數組中的所有矩形相互合並

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

我有一個矩形數組,我想將所有重疊和相鄰的矩形合並到一起。 最終數組不應有重疊或相鄰的矩形。 我嘗試執行以下代碼,但仍然遺留了一些矩形。

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

這是我能夠想出的:

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

讓我們先看看內部循環:

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)

如您所見,我從rects中刪除了一個元素並將其存儲在current_rect中。 然后遍歷 rest 個元素,將其與它們進行比較。 我使用intersects with true作為第二個參數,因此它也將相鄰的矩形視為相交……如果它們相交,我將它們合並。 並且還刪除了rects.remove(index)的另一個元素……我向后迭代,所以我不必調整index

因為我用合並的結果設置了current_rect ( current_rect = current_rect.merge(other_rect) ),所以我可以在同一個循環中繼續合並更多的 rect。

最后,我將最終結果添加到result中。

如果我們看一下中間循環,我們會看到我一直這樣做,直到我用盡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)

由於我只從rects中刪除(通過pop_back或通過remove )它最終必須為空並且循環結束。

現在看看更廣泛的圖景:

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

只要我們合並了一些東西,我們就會繼續循環。 merged變量會跟蹤它。 我將其設置為true以便執行流程進入循環(替代方案是while true進行無限循環並使用break )。

對於循環,我們需要確保merged開始時為false ,並且result為空。 所以我們這樣做。 而且,我們想要迭代過去迭代的結果。 這就是我設置rects = result的原因。 這意味着我需要result中的起始rects 我借此機會制作了一份副本( var result:= rects.duplicate() )。

你應該能夠像這樣使用它:

boxes = combine_rects(boxes)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM