题目:
给你一个以 (radius, xCenter, yCenter) 表示的圆和一个与坐标轴平行的矩形 (x1, y1, x2, y2) ,其中 (x1, y1) 是矩形左下角的坐标,而 (x2, y2) 是右上角的坐标。
如果圆和矩形有重叠的部分,请你返回 true ,否则返回 false 。
换句话说,请你检测是否 存在 点 (xi, yi) ,它既在圆上也在矩形上(两者都包括点落在边界上的情况)。
算法:
方法一:数学
不失一般性,先考虑如何判断圆(xr, yr)和矩形内的点(x, y)是否相交:
如果圆心到(x,y)的距离,小于等于半径,则点在圆内。
如果矩形内有点(x,y)满足这个公式,则矩形和圆相交,否则不相交。
观察这个式子,(, )和r是固定的,要满足这个公式,则要x,y到, 的距离分别都最小。(x, y可以沿坐标轴四个方向移动,x,y之间没有相关性,换而言之,x变大,y可以变大变小)
分类讨论,先考虑x
- x < x1时
| - x| 的最小值为x1 - - x1 <= x <= x2时 | - x| 的最小值为0,此时圆和矩形相交
- x2 < x时
| - x| 的最小值为 - x2
对y也同理。
思路:先考虑一般性,得到一个公式,再观察公式如何取值,能满足条件。
func checkOverlap(radius int, xCenter int, yCenter int, x1 int, y1 int, x2 int, y2 int) bool {
xMin := 0
if xCenter < x1 || x2 < xCenter {
xMin = min(abs(x1 - xCenter), abs(xCenter - x2))
}
yMin := 0
if yCenter < y1 || y2 < yCenter {
yMin = min(abs(y1 - yCenter), abs(yCenter - y2))
}
// fmt.Println(xMin, yMin, xCenter, yCenter)
return xMin * xMin + yMin * yMin <= radius * radius
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func abs(a int) int {
if a < 0 {
return -a
}
return a
}