How to detect that rectangle is going out of the circle or crossing it? Rectangle is a free-flowing inside circle. I know the exact position of the circle and exact position of a rectangle.
-
1There is a rather simple trick used in CG and gaming: enlarge your rectangle by circle radius and then you can just simply check whether circle center point is inside or not. (The latter is range-check of center x and y against rect [xmin, xmax] and [ymin, ymax].) – Scheff's Cat Dec 19 '18 at 08:15
-
If you want to find more, please, try [google "intersection rectangle circle"](https://www.google.com/search?q=intersection+rectangle+circle). – Scheff's Cat Dec 19 '18 at 08:18
-
Is the rectangle axis-aligned or not? – HolyBlackCat Dec 19 '18 at 08:20
-
@Scheff This does not work properly: imagine square (-1-1)(-1,1)(1,1)(1,-1) and circle with radius 1 and center *(.9, 1,9) – MBo Dec 19 '18 at 08:22
-
You should reformulate your problem to "intersection circle segment" (circle vs 4 segments of the rectangle). The answer is [here](https://stackoverflow.com/questions/1073336/circle-line-segment-collision-detection-algorithm). The case inside/outside should be treated separately. – tunglt Dec 19 '18 at 08:27
-
@MBo Forgot the axis-aligned -> center coordinates had to be transformed into axis-aligned coordinate system of rectangle if necessary. Forgot also to mention the "corner" cases. In CG, such thing is used for boundary checks and corner cases are often tolerated because they may produce false positives which have no negative impact than a possibly bit wasted performance... For my luck, I provided that link as well with much more recommendations. ;-) – Scheff's Cat Dec 19 '18 at 08:28
-
1if the distance of each corners of the rectangle to the center of the circle is `<=` radius of circle, then the rectangle is not crossing. – Reblochon Masque Dec 19 '18 at 08:30
3 Answers
Squared distance from circle center to rectangle's closest point can be calculated as (zero denotes circle center is inside rectangle):
dx = Max(Abs(cx - rect.center.x) - rect.width / 2, 0)
dy = Max(Abs(cy - rect.center.y) - rect.height / 2, 0)
SquaredDistance = dx * dx + dy * dy
Then compare it with squared radius

- 77,366
- 5
- 53
- 86
The rectangle has 4 corners, you should check if non of these 4 corners are out of circle. If you have center of circle and it's radius, Distance of every rectangle corners to center of circle must be less than circle radius.

- 379
- 3
- 15
-
1Does not work for square (-1-1)(-1,1)(1,1)(1,-1) and circle with center (0,0) and radius 1.2 - all corners are outside but intersection does exist. – MBo Dec 19 '18 at 08:53
-
1@MBo Question wants to ensure that rectangle is inside the circle so it makes no difference if rectangle is outside or cross it. – Nima Dec 19 '18 at 09:17
I have not perfectly understood your question, I will answer two possible questions:
1) To check whether the rectangle intersects with the circle: You first find the closest point of the rectangle to the center of the circle and then check whether this point is within the circle's radius to the center. Methods like "check only corners" or "check segments of the rectangle" do not work and have counter examples.
Here is an example of the code:
struct Rect
{
double minX, maxX;
double minY, maxY;
};
struct Circle
{
double cX, cY, Radius;
};
double Clamp(double val, double lo, double hi) // use std::clamp if you have C++17
{
if(val < lo) return lo;
if(val > hi) return hi;
return val;
}
double Sqr(double val) {return val*val;}
bool RectangleIntersectsCircle(Rect R, Circle C)
{
double closestX = Clamp(C.cX, R.minX, R.maxX);
double closestY = Clamp(C.cY, R.minY, R.maxY);
return Sqr(closestX - C.cX) + Sqr(closestY - C.cY) < Sqr(C.Radius);
}
2) To check whether rectangle is completely inside the circle: Just check if all 4 corners of the rectangle are inside the circle.
bool RectangleInsideCircle(Rect R, Circle C)
{
double fartherstX = max(fabs(R.minX - C.cX), fabs(R.maxX - C.cX));
double fartherstY = max(fabs(R.minY - C.cY), fabs(R.maxY - C.cY));
return Sqr(fartherstX) + Sqr(fartherstY) < Sqr(C.Radius);
}

- 4,456
- 1
- 11
- 18