本文涉及知识点
计算几何
LeetCode 1401. 圆和矩形是否有重叠
给你一个以 (radius, xCenter, yCenter) 表示的圆和一个与坐标轴平行的矩形 (x1, y1, x2, y2) ,其中 (x1, y1) 是矩形左下角的坐标,而 (x2, y2) 是右上角的坐标。
如果圆和矩形有重叠的部分,请你返回 true ,否则返回 false 。
换句话说,请你检测是否 存在 点 (xi, yi) ,它既在圆上也在矩形上(两者都包括点落在边界上的情况)。
示例 1 :
输入:radius = 1, xCenter = 0, yCenter = 0, x1 = 1, y1 = -1, x2 = 3, y2 = 1
输出:true
解释:圆和矩形存在公共点 (1,0) 。
示例 2 :
输入:radius = 1, xCenter = 1, yCenter = 1, x1 = 1, y1 = -3, x2 = 2, y2 = -1
输出:false
示例 3 :
输入:radius = 1, xCenter = 0, yCenter = 0, x1 = -1, y1 = 0, x2 = 0, y2 = 1
输出:true
提示:
1 <= radius <= 2000
-104 <= xCenter, yCenter <= 104
-104 <= x1 < x2 <= 104
-104 <= y1 < y2 <= 104
计算几何
借用LeetCode 龅牙叔的图。
看是否符合以下三种情况之一:
一,圆心在红色矩形内。
二,圆心在绿色矩形内。
三,圆心在原始矩形四个顶点为圆心,Radius为半径的圆内。
代码
核心代码
class Solution {
public:
bool checkOverlap(int radius, int xCenter, int yCenter, int x1, int y1, int x2, int y2) {
auto Dis2 = [](long long x1, long long y1, int x2, int y2){
return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
};
auto IsCycle = [&](int x, int y) {
return Dis2(x, y, xCenter, yCenter) <= (long long)radius * radius;
};
auto IsRect = [&](int x1, int y1, int x2, int y2) {
return (xCenter >= x1) && (xCenter <= x2) && (yCenter >= y1) && (yCenter <= y2);
};
return IsCycle(x1, y1) || IsCycle(x1, y2) || IsCycle(x2, y1) || IsCycle(x2, y2) ||
IsRect(x1, y1 - radius, x2, y2 + radius) || IsRect(x1 - radius, y1 , x2 + radius, y2 );
}
};
单元测试
int radius, xCenter, yCenter, x1, y1, x2, y2;
TEST_METHOD(TestMethod11)
{
radius = 1, xCenter = 0, yCenter = 0, x1 = 1, y1 = -1, x2 = 3, y2 = 1;
auto res = Solution().checkOverlap(radius, xCenter, yCenter, x1, y1, x2, y2);
AssertEx(true, res);
}
TEST_METHOD(TestMethod12)
{
radius = 1, xCenter = 1, yCenter = 1, x1 = 1, y1 = -3, x2 = 2, y2 = -1;
auto res = Solution().checkOverlap(radius, xCenter, yCenter, x1, y1, x2, y2);
AssertEx(false, res);
}
TEST_METHOD(TestMethod13)
{
radius = 1, xCenter = 0, yCenter = 0, x1 = -1, y1 = 0, x2 = 0, y2 = 1;
auto res = Solution().checkOverlap(radius, xCenter, yCenter, x1, y1, x2, y2);
AssertEx(true, res);
}