[Leetcode] 5361. Whether circle and rectangle overlap (Circle and Rectangle Overlapping)


Title description

[Leetcode] 5361. Whether circle and rectangle overlap (Circle and Rectangle Overlapping)

Give you a circle represented by (radius, x_center, y_center) and a rectangle parallel to the coordinate axis (x1, y1, x2, y2), where (x1, y1) are the coordinates of the lower left corner of the rectangle, (x2, y2) Are the coordinates of the upper right corner.

If the circle and rectangle overlap, please return True, otherwise return False.

In other words, please check whether there is a point (xi, yi), which is both on the circle and the rectangle (both include the case where the point falls on the boundary).

Example 1:
Insert picture description here
Input: radius = 1, x_center = 0, y_center = 0, x1 = 1, y1 = -1, x2 = 3, y2 = 1
Output: true
Explanation: Circle and rectangle have a common point (1,0)

Example 2:
Insert picture description here
Input: radius = 1, x_center = 0, y_center = 0, x1 = -1, y1 = 0, x2 = 0, y2 = 1
Output: true

Example 3:
Insert picture description here
Input: radius = 1, x_center = 1, y_center = 1, x1 = -3, y1 = -3, x2 = 3, y2 = 3
Output: true

Example 4:
Input: radius = 1, x_center = 1, y_center = 1, x1 = 1, y1 = -3, x2 = 2, y2 = -1
Output: false

prompt:

  • 1 <= radius <= 2000
  • -10^4 <= x_center, y_center, x1, y1, x2, y2 <= 10^4
  • x1 < x2
  • y1 < y2

First answer

Ideas
Because the coordinates are plastic, it can be violent. Traverse each pixel in the square area to determine whether it is within the circle.

Code:

class Solution {
    
    
public:
    bool checkOverlap(int radius, int x_center, int y_center, int x1, int y1, int x2, int y2) {
    
    
        long r2 = radius*radius;
        for(int y=y1; y<=y2; y++){
    
    
            for(int x=x1; x<=x2; x++){
    
    
                int dx = x-x_center;
                int dy = y-y_center;
                long d = dx*dx + dy*dy;
                if(d <= r2)
                    return true;
            }
        }
        return false;
    }
};

result:
Insert picture description here

Second answer

Ideas I
saw a more general method, which should be able to be used when most rectangular areas intersect.
Regional division method. The space is divided into 9 regions, and the circle adopts different strategies in different regions. For details, please refer to here. The
divided areas are as shown in the figure below: The
Insert picture description here
intersection of circles and rectangles can be classified into the following three types:
Insert picture description here

Code:

// 思路:
// 数学思路不是每一题都适用,因此这里尝试一下看似普适的区域划分方法


class Solution {
    
    
public:
    bool checkOverlap(int radius, int x_center, int y_center, int x1, int y1, int x2, int y2) {
    
    
        
        // 圆心在矩形内情况
        if(x1 <= x_center && x_center <= x2 && y1 <= y_center && y_center <= y2)
            return true;
        
        // 圆心在矩形上下左右区域
        // 上
        if(x1 <= x_center && x_center <= x2 && y_center >= y2 && y_center-y2 <= radius)
            return true;
        // 下
        if(x1 <= x_center && x_center <= x2 && y_center <= y1 && y1 - y_center <= radius)
            return true;
        // 左
        if(y1 <= y_center && y_center <= y2 && x_center <= x1 && x1-x_center <= radius)
            return true;
        // 右
        if(y1 <= y_center && y_center <= y2 && x_center >= x2 && x_center-x2 <= radius)
            return true;

        // 圆心在矩形斜对角线上
        long r2 = radius*radius;
        if(abs(x1-x_center)*abs(x1-x_center) + abs(y2-y_center)*abs(y2-y_center) <= r2)
            return true;
        if(abs(x1-x_center)*abs(x1-x_center) + abs(y1-y_center)*abs(y1-y_center) <= r2)
            return true;
        if(abs(x2-x_center)*abs(x2-x_center) + abs(y1-y_center)*abs(y1-y_center) <= r2)
            return true;
        if(abs(x2-x_center)*abs(x2-x_center) + abs(y2-y_center)*abs(y2-y_center) <= r2)
            return true;


        return false;
    }
};

result:
Insert picture description here

Third answer

Idea The
first wifiiisolution in China in the Weekly Competition .
This solution can be understood from the perspective of the area division method.
The intersection of a circle and a rectangle can be classified into the following three situations. In the figure, Figure 1 can be used to determine whether the center of the circle is within the rectangle, and Figure 2 can be used to determine whether the four corners of the rectangle are within the circle, but Figure 3 is more troublesome, and there is no corresponding point to bring in to determine the intersection wifiii. The algorithm concisely realizes the judgment of the third case.
Three kinds:
Insert picture description here

Code:

// 思路:
// 周赛冠军的解法,用区域划分来理解的话,它的方法是简洁的实现了当圆心在矩形外的上下左右区域的相交判断
class Solution {
    
    
public:
    bool checkOverlap(int radius, int x_center, int y_center, int x1, int y1, int x2, int y2) {
    
    
        auto incircle = [&](int x, int y){
    
    return (x-x_center)*(x-x_center) + (y-y_center)*(y-y_center) <= radius*radius;};
        auto insqure = [&](int x, int y){
    
    return x1 <= x && x <= x2 && y1 <= y && y <= y2;};
		
		// 这里组合有9个坐标,其中圆心和四个角点,这五个坐标可以判断图1和图2的相交情况。
		// 剩下4个坐标用于判断图3那种相交情况
        vector<int> vx{
    
    x_center, x1, x2}, vy{
    
    y_center, y1, y2};
        bool is_ok = false;
        for(auto & xx : vx)
            for(auto & yy : vy)
                if(incircle(xx, yy) && insqure(xx, yy))
                    is_ok = true;
        return is_ok;
    }
};

result:
Insert picture description here

Fourth answer

Idea
Mathematical method. Refer to know the method here .
Note that this method is the best in theory, but decimals are generated in the actual process, so there is a certain error. The process is as follows:
first map the center of the circle to the first quadrant:
Insert picture description here
then judge the size of the vector u and the size of the radius to get the intersection:
Insert picture description here

Code:

// 思路:
// 用[知乎这里提到的方法](https://www.zhihu.com/question/24251545/answer/27184960)
class Solution {
    
    
public:
    bool checkOverlap(int radius, int x_center, int y_center, int x1, int y1, int x2, int y2) {
    
    
        // 向量cp转到第一象限
        double cpx = abs(x_center-(x1+x2)/2.0);
        double cpy = abs(y_center-(y1+y2)/2.0);
        double hx = x2 - (x1+x2)/2.0;
        double hy = y2 - (y1+y2)/2.0;

        double ux = max(cpx-hx, 0.0);
        double uy = max(cpy-hy, 0.0);

        return ux*ux + uy*uy <= radius*radius;
    }
};

result:
Insert picture description here

Related/reference links

Guess you like

Origin blog.csdn.net/a435262767/article/details/105334986