2012-12-31 102 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) 
    }