Circle and Rectangle Overlapping 圆和矩形是否有重叠
问题描述:
给你一个以 (radius, xCenter, yCenter) 表示的圆和一个与坐标轴平行的矩形 ( x 1 x_1 x1, y 1 y_1 y1, x 2 x_2 x2, y 2 y_2 y2) ,其中 ( x 1 x_1 x1, y 1 y_1 y1) 是矩形左下角的坐标,而 ( x 2 x_2 x2, y 2 y_2 y2) 是右上角的坐标。
如果圆和矩形有重叠的部分,请你返回 true ,否则返回 false 。
换句话说,请你检测是否 存在 点 ( x i x_i xi, y i y_i yi) ,它既在圆上也在矩形上(两者都包括点落在边界上的情况)。
**radius 范围[1,2000] **
xCenter, yCenter范围[ − 1 0 4 -10^4 −104, 1 0 4 10^4 104]
x 1 x_1 x1, y 1 y_1 y1范围[ − 1 0 4 -10^4 −104, 1 0 4 10^4 104]
x 2 x_2 x2, y 2 y_2 y2范围[ − 1 0 4 -10^4 −104, 1 0 4 10^4 104]
分析
如果要确定是否有重叠,就需要在矩形上找到一个点,并且与圆心的距离<=radius.
一种方式就是枚举矩形边上的点,包括顶点。因为条件中给出的坐标都是int,所以不存在小数。因此可以枚举每一个边上的坐标点,一条边的范围是[1,
2
∗
1
0
4
2*10^4
2∗104],如果对4个边都计算一遍,理论上也是可以的。
但是如果条件中给出的坐标是
d
o
u
b
l
e
double
double,这种暴力枚举的方式,就无法处理。因为每2个整数之间的小数太多,无法进行枚举。
而在此方法中,也不需要枚举所有的边,可以判断圆和矩形的相对位置,来决定用哪一条边来验证。
换一个角度思考,还是基于假设圆心坐标O(
x
,
y
x,y
x,y),而矩形的左下角(
x
l
,
y
l
xl,yl
xl,yl),右上角(
x
r
,
y
r
xr,yr
xr,yr),那么如果坐标点p(
p
x
,
p
y
px,py
px,py)在矩形中,必然满足px属于
[
x
l
,
x
r
]
[xl,xr]
[xl,xr]&&py属于
[
y
l
,
y
r
]
[yl,yr]
[yl,yr].
而p与圆心O的距离为
d
i
s
2
=
[
a
b
s
(
p
x
−
x
)
]
2
+
[
a
b
s
(
p
y
−
y
)
]
2
dis^2 = [abs(px-x)]^2+[abs(py-y)]^2
dis2=[abs(px−x)]2+[abs(py−y)]2.如果
d
i
s
t
2
<
=
r
a
d
i
u
s
2
dist^2<=radius^2
dist2<=radius2,可以存在,就说明2者必然重合。
所以问题就变成数值q在区间
[
L
,
R
]
[L,R]
[L,R]中找到一个
a
b
s
(
q
−
X
)
abs(q-X)
abs(q−X)的最小值。
代码
public boolean checkOverlap(int radius, int xCenter, int yCenter, int x1, int y1, int x2, int y2) {
double dist = 0;
if (xCenter < x1 || xCenter > x2) {
dist += Math.min(Math.pow(x1 - xCenter, 2), Math.pow(x2 - xCenter, 2));
}
if (yCenter < y1 || yCenter > y2) {
dist += Math.min(Math.pow(y1 - yCenter, 2), Math.pow(y2 - yCenter, 2));
}
return dist <= radius * radius;
}
时间复杂度 O ( 1 ) O(1) O(1)
空间复杂度 O ( 1 ) O(1) O(1)
Tag
Math
Geometry