2010-08-10 161 views
2

我有複雜的多邊形,我知道最小x,最小y,最大x和最大y。我也有另一個矩形,我知道左上角和右下角的頂點。知道這些信息,我怎麼知道這兩個邊框是否碰撞?謝謝邊界矩形碰撞測試?

回答

3

嘗試這樣:

typedef struct rect { 
    int top;  // maximum y-coord 
    int bottom; // minimum y-coord 
    int left; // minimum x-coord 
    int right; // maximum x-coord 
} rectangle; 

// Returns 1 if the point (x, y) lies within the rectangle, 0 otherwise 
int is_point_in_rectangle(rectangle r, int x, int y) { 
    if ((r.left <= x && r.right >= x) && 
     (r.bottom <= y && r.top >= y)) 
     return 1; 
    return 0; 
} 

// Returns 1 if the rectangles overlap, 0 otherwise 
int do_rectangles_intersect(rectangle a, rectangle b) { 
    if (is_point_in_rectangle(a, b.left , b.top ) || 
     is_point_in_rectangle(a, b.right, b.top ) || 
     is_point_in_rectangle(a, b.left , b.bottom) || 
     is_point_in_rectangle(a, b.right, b.bottom)) 
     return 1; 
    if (is_point_in_rectangle(b, a.left , a.top ) || 
     is_point_in_rectangle(b, a.right, a.top ) || 
     is_point_in_rectangle(b, a.left , a.bottom) || 
     is_point_in_rectangle(b, a.right, a.bottom)) 
     return 1; 
    return 0; 
} 

您可以爲任何多邊形做同樣的,只是遍歷所有的點,並呼籲is_point_in_rectangle他們。由於您只有複雜多邊形的邊界框,因此此方法可能會出現誤報(即,矩形位於複雜多邊形的邊界框內,但位於多邊形本身之外)。但是,這種限制適用於將複雜形狀簡化爲邊界框的任何方法。

+0

我懷疑這個算法比需要更難。至少,do_rectangles_intersect()中的第二組測試是多餘的。 – 2010-08-11 00:48:49

+0

我如何更正確地做到這一點,以避免誤報?謝謝 – jmasterx 2010-08-11 00:48:59

+0

@ Brian-第二個測試是檢測矩形A完全位於矩形B內的情況。矩形重疊,但B的角落都不在A內。您必須檢查相反方向。 @ Jex-如果您在複雜多邊形上使用邊界矩形,則無法避免誤報。如果你想檢測矩形和任意多邊形之間的碰撞,那完全是一個完全不同的問題。 – bta 2010-08-11 00:52:21

2

如果區間[Ax1,Ax2]和[Bx1,Bx2]重疊,區間[Ay1,Ay2]和[By1,By2]重疊,則矩形A和B發生碰撞。

+2

該OP提到了一個複雜的多邊形,所以我認爲這個測試過於嚴格,儘管速度很快。 – ysap 2010-08-11 00:04:21

+1

@yasp:消除無法觸摸的多邊形可能很有用,因此修剪需要使用更昂貴的方法進行檢查的對的數量。 – Akusete 2010-08-11 00:27:16

+0

@ ysap- OP有*複雜多邊形的矩形邊界框*。這種方法適用於任何兩個矩形,所以它應該是一個有效的解決方案。如果OP使用原始的多邊形而不僅僅是一個邊界框,那麼是的,我同意你對這種方法的保留。 – bta 2010-08-11 00:31:23

0

我覺得下面的作品大多數的時代,但它肯定比邊界框檢查更準確,雖然比較複雜。看看以下問題:

Polygon in rectangle algorithm?

在那裏,您會看到找出一種算法,如果一個點是多邊形內。您可以將此測試應用於第一個poly w.r.t的每個點。第二個。然後是相反的。如果測試通過至少一次,就會發生碰撞。

0

創建矩形左右邊緣的x座標的排序數組。然後,使用「掃描線」通過矩形從左向右移動。保留一個二叉搜索樹,該樹包含與掃描線重疊的矩形的頂部和底部邊緣的y座標。對於數組的每個元素,檢查它是左邊還是右邊。如果是右邊緣,請從BST上取下相應的頂部和底部邊緣。如果它是左邊緣,則在BST中搜索與當前矩形重疊的矩形;如果有,返回重疊。然後,將矩形頂部和底部邊緣的y座標添加到BST。搜索需要O(n log n)時間,因爲需要O(n log n)時間對矩形進行排序,並且每次2n次迭代需要O(log n)時間 - 從谷歌搜索結果複製。

+1

這聽起來像確定兩個矩形是否重疊的矯枉過正。對於任意數量的矩形來說,這可能是一個很好的解決方案,但是這個特殊問題只能使用兩個。對於任意數量的矩形,它適用於 – bta 2010-08-11 00:33:41

+0

。認爲它可能有幫助。 – joshu 2010-08-11 01:11:53