4

How can I check if a Circle completely contains a Rectangle (in 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) {
   ...
}
CodeGuy
  • 28,427
  • 76
  • 200
  • 317

4 Answers4

8

Below is answer for cartesian axis where (0, 0) lies on bottom-left corner.

EDIT Since your x, y are top left corner of square. Transform them to be in center:

x = x+r
y = y-r

Equation of circle is x^2 + y^2 = r^2, now given point {x, y} will lie within or on the circle when iff x^ + y^2 <= r^2. Now, we can safety make an assumption that rectangle will lie within circle if all fours corner points lies within or on the circle. Using above assumption pseudo-code for finding if rectangle is contained in circle:

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 More optimized approach for calculation (suggested by Jim in comments below) would be by calculating the most farthest corner of rectangle from the center of the circle:

dx = max(centerX - rectLeft, rectRight - centerX); 
dy = max(centerY - rectTop, rectBottom - centerY);
return radius*radius >= dx*dx + dy*dy
Shivam
  • 2,134
  • 1
  • 18
  • 28
  • This is wrong, since (c.x, c.y) is the upper left corner of the bounding rectangle of the circle, not its center (a rather poor way to define a circle, but that's the OP's problem). Also, you don't need a loop ... just check whether the corner furthest from the center is within the circle. – Jim Balter Sep 15 '15 at 06:40
  • @JimBalter You're right, we can check farthest point but I believe that would require to calculate distances as well, so complexity of the solution might just stay same. Also, my answer was under assuming that c.x and x.y are center of the circle. – Shivam Sep 16 '15 at 02:52
  • @User104 No, it's not complex: `dx = max(centerX - rectLeft, rectRight - centerX); dy = max(centerY - rectTop, rectBottom - centerY); return radius*radius >= dx*dx + dy*dy` P.S. a) I know what you assumed, but it doesn't match the question. b) `^` is exclusive or, not exponentiation. – Jim Balter Sep 16 '15 at 03:34
  • @JimBalter Indeed. Though, your approach may not be optimized when rectangle is rotated but for OP's question this should be more optimized way for calculation. Thanks for pointing that out. I've made edits to my original answer. – Shivam Sep 16 '15 at 04:06
  • 1
    The solution you have put in edit is wrong, it at least should be calculating the `abs()` values for each of the arguments of `max()` function. Try it with `circle(r=10,x=0,y=0)` and `rectangle(tlcX=0, tlcY=0,w=10,h=10)` and you will see what I mean. – Serhiy Jan 31 '17 at 23:42
  • Indeed, code in EDIT is wrong. ABS is missing. Swift code in my answer. – sabiland Jan 03 '18 at 18:33
4

Probably the easiest way is to check if all four corners of the rectangle are less than radius units away from the center of the circle. If they are, then all points in the rectangle are inside the circle. The four points that you have to check are (x, y), (x + width, y), (x, y + height), and (x + width, y + height).

Note: It's strange that the circle is defined from the top right corner, while the rectangle is defined from the top left. Make sure you take that into account when computing the center of the circle.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
  • 1
    Check the corner furthest from the center rather than checking all four corners: max(sq(centerX - rectLeft), sq(centerX - rectRight)) + max(sq(centerY - rectTop), sq(centerY - rectBottom)) <= sq(radius) – Jim Balter Sep 15 '15 at 06:44
0

Swift 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)
    }
sabiland
  • 2,526
  • 1
  • 25
  • 24
-1

i know i'm late but i wanted to share my idea, and if there's something wrong with it. i just used width/2 and height/2 to define half of height and half of width. Next i used pythagorean theorem to calculate distance from center to corner and then just checked if its bigger than radius or not. I know its java, but i can't code in it, but i want make same program in c++. anyway here's code:

#include <iostream>
#include <math.h>

using namespace std;

void rectangle_in_circle(float w, float h,float r){
    //sides of square triangle
    float a;
    float b;
    float c;
    //pythagorean theorem
    b = h/2;
    a = w/2;
    c = sqrt(pow(b,2) + pow(a,2));
    //output
    if(c <= r){
        cout << "true" << endl;
    }else{
        cout << "false" << endl;
    }
    }

int main(){ 

    rectangle_in_circle(4,7,5);
    return 0;
}
Staś
  • 11
  • 1