2012-12-31 100 views
1

如何檢查Circle 完全是否包含Rectangle(Java)?檢查圓形是否包含矩形

public class Circle { 
    //x and y define the top left corner of the square bounding this circle 
    public int x, y, radius; 
} 

public class Rectangle { 
    //x and y define the top left corner 
    public int x, y, width, height; 
} 

public boolean circleContainsRectangle(Circle circle, Rectangle rect) { 
    ... 
} 
+0

@Codeguy多少代碼,您有WRI到目前爲止解決它? – vikiiii

回答

3

以下是對cartesian軸的回答,其中(0, 0)位於左下角。

編輯 由於您的x, y是正方形的左上角。變換他們在中心:

x = x+r 
y = y-r 

公式是x^2 + y^2 = r^2,現在給點{x, y}將內或圓上撒謊IFF x^ + y^2 <= r^2時。現在,我們可以安全地假設,如果所有四個角點位於圓內或圓上,矩形將位於圓內。使用上述假設僞碼爲如果矩形包含在圓發現:

boolean contains(Circle c) { 
    Point p_rect_1 = {x, y}; 
    Point p_rect_2 = {x + width, y }; 
    Point p_rect_3 = {x + width, y + height }; 
    Point p_rect_4 = {x, y + height }; 
    Point[] points = new Point[] { p_rect_1, p_rect_2, p_rect_3, p_rect_4 }; 

    foreach(Point p : points) { 
     // ** is raise to power 
     if ((c.x - p.x)**2 + (c.y - p.y)**2 > c.r**2) { 
      return false; 
     } 
    } 
    return true; 
} 

EDIT 進行計算(在下面的評論由吉姆建議的)更優化的方法是通過從計算矩形的最最遠的角落圓的中心:

dx = max(centerX - rectLeft, rectRight - centerX); 
dy = max(centerY - rectTop, rectBottom - centerY); 
return radius*radius >= dx*dx + dy*dy 
+0

+1對於瘋狂的心靈內爆的數學:P – MadProgrammer

+0

這是錯誤的,因爲(cx,cy)是圓的邊界矩形的左上角,而不是它的中心(一個相當差的方式來定義一個圓圈,但這是OP的問題)。此外,您不需要循環...只需檢查距離中心最遠的角落是否在圓圈內。 –

+0

@JimBalter你說得對,我們可以檢查最遠點,但我相信這也需要計算距離,所以解決方案的複雜性可能會保持不變。另外,我的回答是假設c.x和x.y是圓圈的中心。 – Shivam

3

也許最簡單的方法是檢查是否矩形的所有四個角都是從圓心不到radius單位處。如果是,那麼矩形中的所有點都在圓內。您必須檢查的四個點是(x,y),(x +寬度,y),(x,y +高度)和(x +寬度,y +高度)。

注意:奇怪的是,圓是從右上角定義的,而矩形是從左上角定義的。確保在計算圓心時考慮到這一點。

+1

檢查離中心最遠的角落,而不是檢查所有四個角:最大(sq(centerX - rectLeft),sq(centerX - rectRight))+ max(sq(centerY - rectTop),sq(centerY - rectBottom))< = sq(radius) –

0

斯威夫特4:

func checkCircleContainsRect(circle: Circle, rect: CGRect) -> Bool 
    { 
     let dx = max(abs(circle.position.x - rect.minX), abs(rect.maxX - circle.position.x)) 
     let dy = max(abs(circle.position.y - rect.maxY), abs(rect.minY - circle.position.y)) 
     return (circle.radius * circle.radius) >= (dx * dx) + (dy * dy) 
    }