[Leetcode] 5361. Si el círculo y el rectángulo se superponen (superposición de círculo y rectángulo)


Descripción del Título

[Leetcode] 5361. Si el círculo y el rectángulo se superponen (superposición de círculo y rectángulo)

Darle un círculo representado por (radio, x_center, y_center) y un rectángulo paralelo al eje de coordenadas (x1, y1, x2, y2), donde (x1, y1) son las coordenadas de la esquina inferior izquierda del rectángulo, (x2, y2) Son las coordenadas de la esquina superior derecha.

Si el círculo y el rectángulo se superponen, devuelva True; de ​​lo contrario, devuelva False.

En otras palabras, verifique si hay un punto (xi, yi), que esté tanto en el círculo como en el rectángulo (ambos incluyen el caso en el que el punto cae en el límite).

Ejemplo 1:
Inserte la descripción de la imagen aquí
Entrada: radio = 1, x_center = 0, y_center = 0, x1 = 1, y1 = -1, x2 = 3, y2 = 1
Salida: verdadero
Explicación: Círculo y rectángulo tienen un punto común (1,0)

Ejemplo 2:
Inserte la descripción de la imagen aquí
Entrada: radio = 1, x_center = 0, y_center = 0, x1 = -1, y1 = 0, x2 = 0, y2 = 1
Salida: verdadero

Ejemplo 3:
Inserte la descripción de la imagen aquí
Entrada: radio = 1, x_center = 1, y_center = 1, x1 = -3, y1 = -3, x2 = 3, y2 = 3
Salida: verdadero

Ejemplo 4:
Entrada: radio = 1, x_center = 1, y_center = 1, x1 = 1, y1 = -3, x2 = 2, y2 = -1
Salida: falso

rápido:

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

Primera respuesta

Ideas
Como las coordenadas son de plástico, puede ser violento. Recorra cada píxel en el área del cuadrado para determinar si está dentro del círculo.

Código:

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;
    }
};

resultado:
Inserte la descripción de la imagen aquí

Segunda respuesta

Ideas
Vi un método más general, que debería poder usarse cuando la mayoría de las áreas rectangulares se cruzan.
Método de división regional. El espacio se divide en 9 regiones y el círculo adopta diferentes estrategias en diferentes regiones. Para obtener más información, consulte aquí. Las
áreas divididas son las que se muestran en la siguiente figura: La
Inserte la descripción de la imagen aquí
intersección de círculos y rectángulos se puede clasificar en los siguientes tres tipos:
Inserte la descripción de la imagen aquí

Código:

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


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;
    }
};

resultado:
Inserte la descripción de la imagen aquí

Tercera respuesta

Idea La
primera wifiiisolución en China en la Competencia Semanal .
Esta solución puede entenderse desde la perspectiva del método de división de áreas.
La intersección de un círculo y un rectángulo se puede clasificar en las siguientes tres situaciones. En la figura, la Figura 1 se puede usar para determinar si el centro del círculo está dentro del rectángulo, y la Figura 2 se puede usar para determinar si las cuatro esquinas del rectángulo están dentro del círculo, pero la Figura 3 es más problemática y no hay un punto correspondiente que traer para determinar la intersección wifiii. El algoritmo realiza de forma concisa el juicio del tercer caso.
Tres tipos:
Inserte la descripción de la imagen aquí

Código:

// 思路:
// 周赛冠军的解法,用区域划分来理解的话,它的方法是简洁的实现了当圆心在矩形外的上下左右区域的相交判断
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;
    }
};

resultado:
Inserte la descripción de la imagen aquí

Cuarta respuesta

Idea
Método matemático. Consulte para conocer el método aquí .
Tenga en cuenta que este método es el mejor en teoría, pero los decimales se generan en el proceso real, por lo que existe un cierto error. El proceso es el siguiente:
primero mapee el centro del círculo al primer cuadrante:
Inserte la descripción de la imagen aquí
luego juzgue el tamaño del vector u y el tamaño del radio para obtener la intersección:
Inserte la descripción de la imagen aquí

Código:

// 思路:
// 用[知乎这里提到的方法](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;
    }
};

resultado:
Inserte la descripción de la imagen aquí

Enlaces relacionados / de referencia

Supongo que te gusta

Origin blog.csdn.net/a435262767/article/details/105334986
Recomendado
Clasificación