- 圆心(xCenter, yCenter);半径radius
- 矩形左下角(x1, y1), 矩形右上角(x2, y2)
圆和矩形相对的位置有九种情况,如下图,其中 5标记的区域 认为是矩形。圆心可能出现在这九个区域中的任意一个区域。我们可以通过计算圆心到矩形的最小的距离distance,来判断圆形是否和矩形有重叠的部分。
- 如果 distance 小于等于圆形的半径,说明圆形和矩形有重叠的部分
- 如果 distance 大于圆形的半径,说明圆形和矩形没有重叠的部分
计算 distance 的方式
对这九种情况进一步总结,可以发现,实际上只有四种情况,分别是
- 圆心在矩形内部,即区域5
- 圆心在矩形对角的区域,即区域1,3,7,9
- 圆心的 xCenter 在矩形左右两边之间,即区域2,8
- 圆心的 yCenter 在矩形上下两边之间,即区域4, 6
- 对于情况1,计算圆心的坐标是否在矩形的范围内即可;
- 对于情况2,矩形与圆心最近的点是矩形四个顶点中距离圆心最近的一个顶点,计算圆心和顶点的距离进行判断
- nearestX = min(|xCenter - x1|, |xCenter - x2|)
- nearestY = min(|yCenter - y1|, |yCenter - y2|)
- 对于情况3,已经知道 圆心的 xCenter 在矩形x1,x2之间了,只需要判断,圆心的 yCenter 和 y1, y2的距离是否小于圆形半径的距离
- 对于情况4,与情况3同理,已经知道 圆心的 yCenter 在矩形y1,y2之间了,只需要判断,圆心的 xCenter 和 x1, x2的距离是否小于圆形半径的距离
class Solution {
public boolean checkOverlap(int radius, int xCenter, int yCenter, int x1, int y1, int x2, int y2) {
// 圆心在矩形里面
if (xCenter <= x2 && xCenter >= x1 && yCenter <= y2 && yCenter >= y1) {
return true;
}
// 找圆心和矩形距离最近的点
int distanceX = Math.min(Math.abs(xCenter - x1), Math.abs(xCenter - x2));
int distanceY = Math.min(Math.abs(yCenter - y1), Math.abs(yCenter - y2));
// 圆心 x 坐标在,矩形左右两条边的范围内,判断圆心到矩形上下两边最小的距离
if (xCenter <= x2 && xCenter >= x1) {
return radius >= distanceY;
}
// 圆心 x 坐标在,矩形上下两条边的范围内,判断圆心到矩形左右两边最小的距离
if (yCenter <= y2 && yCenter >= y1) {
return radius >= distanceX;
}
// 判断矩形对于圆心距离最近的一个角,与圆心之间的距离
return radius * radius >= distanceX * distanceX + distanceY * distanceY;
}
}