Encuentra el mejor ajuste para el círculo más cercano

12

A continuación se muestra una imagen de ejemplo, si tengo un punto del punto blanco en el medio y quiero encontrar la ubicación más cercana posible para el círculo azul (que obviamente está en la ubicación donde lo coloqué) si ya existen todos los círculos rojos . ¿Cómo puedo encontrar esa ubicación?

El rendimiento para mí no es una preocupación importante para esta aplicación.

ingrese la descripción de la imagen aquí

Botánico
fuente
1
¿Cuál es el significado del círculo negro? ¿Puedes colocar el círculo azul sobre él?
Ewan
2
Entonces, para que quede claro, ¿desea la ubicación donde puede colocar el círculo azul de modo que sea la distancia más corta posible desde el punto blanco sin superponer ninguno de los otros círculos?
Robert Harvey
3
Relacionado: Empaque circular
Robert Harvey
2
¿Tocarán siempre todos los círculos algún otro círculo en al menos un lugar?
Robert Harvey
3
Relacionado: stackoverflow.com/questions/10666116 y stackoverflow.com/questions/5509151 . También posiblemente relevante: stackoverflow.com/a/19375601
Robert Harvey

Respuestas:

4

Esta no es una solución general, ya que hay varias situaciones en las que no proporcionará la posición del círculo azul con la distancia más corta al punto blanco. Por ejemplo, si tiene 100 bolas rojas agrupadas y el punto blanco está muy lejos de este grupo de bolas rojas, entonces ninguna de las bolas rojas tendrá influencia en la posición del círculo azul que puede centrarse en el punto blanco. . Tampoco mostrará todos los detalles de los cálculos. De todos modos, para un subconjunto de configuraciones, donde la solución (círculo azul) es tangente a dos círculos rojos, debería funcionar lo siguiente:
1) dejar que R sea el radio del círculo azul
2) hacer un bucle sobre todos los pares de círculos rojos, sí Sé que esto es O (n2).
3) para cada par de círculos i, j con centros en (xi, yi) y (xj, yj) con el radio respectivo ri y rj, calcule el cuadrado de la distancia entre el par de círculos

d_ij^2=(xi-xj)^2+(yi-yj)^2  

4) pon todos los pares de círculos que

dij^2<R^2

en una lista

5) recorra la lista, encontrando las 2 soluciones de círculos de radio R tangente a ambos círculos i y j. Para hacer esto, use estas ecuaciones junto con esta imagen dos circulos azules para un par de circulos rojos

a = R+ri  
b = R+rj  
c = dij  
α = arccos((b^2+c^2-a^2)/(2bc)  

con la información anterior puede encontrar (X1ij, Y1ij) y (X2ij, Y2ij) los centros de los 2 círculos tangentes a los círculos i y j. Para cada candidato, haga un círculo azul sobre todos los demás círculos rojos y vea si no se superpone. Si lo descartan, si no, verifique la distancia al círculo blanco. Si mantiene el que tiene una distancia menor, creo que tendrá la solución cuando termine de recorrer la lista de pares de círculos. El algoritmo parece O (n3).

Mandril
fuente
no funciona cuando solo hay un círculo
Ewan
o dos círculos pero con un punto objetivo fuera de ambos
Ewan
el problema es que no puedes estar seguro de que tienes todos los casos límite
Ewan
además. existen soluciones únicas para esos casos
Ewan
Debe anotar todos los supuestos bajo los cuales la solución es correcta o al menos señalar todos los casos límite. Algunos de ellos pueden ser obvios, pero otros no. Por ejemplo, esto no funcionará si es posible dibujar una línea que separe el punto blanco de todos los círculos rojos y el punto blanco esté a menos de R del círculo más cercano.
Vlad
2

La ubicación más cercana al punto estará en el punto o tocando un círculo.

por lo tanto, primero verifique el punto, luego gire el nuevo círculo alrededor del borde de cada círculo existente, calcule la distancia desde el punto y si se superpone a medida que avanza y realice un seguimiento del punto de distancia mínima. Detente cuando hayas atravesado todos los círculos.

es decir. verifique todos los puntos en las líneas verdes, más el círculo blanco. donde la línea verde es un círculo con radio del rojo más el azul

posibles puntos centrales

debe verificar toda la línea verde, no solo las intersecciones, de modo que cubra estos casos extremos.

casos de círculo único

Obviamente, el tamaño del paso de su recorrido será importante en términos de rendimiento. Pero como dice que el rendimiento no es un problema, elija el valor correspondiente a la resolución de su valor de salida. es decir, flotar, largo?

aclaración:

mi sugerencia es forzar la fuerza bruta en todos los puntos alrededor de cada círculo, probando la superposición con todos los otros círculos en cada punto. Sin inteligencia.

Si la foto de ejemplo es indicativa de la cantidad de círculos y la resolución, no debería ser un problema para una PC estándar

tenemos 20 círculos de radio promedio 200, por lo que es aproximadamente 20 * 2 π * 200 puntos * 20 pruebas de intersección = 4800000 iteraciones

Nota:

Los enfoques iterativos como este son defectuosos porque el tamaño de su paso, en este caso la resolución de su salida, puede afectar en gran medida el resultado.

Digamos que tengo dos círculos rojos separados por 2 píxeles y un círculo azul de 1 píxel de radio para apretar entre ellos. Claramente, con cualquiera de los dos píxeles como centro del círculo azul, se superpondrá a uno de los rojos. pero obviamente hay espacio para el círculo si el centro se encuentra entre los dos píxeles.

De ahí mi comentario preguntando sobre la resolución de la salida. lo que dijiste podría ser cualquier cosa.

También puede resolver la ecuación simultánea para cada par de círculos con un aumento del radio en el radio del círculo azul.

esto le dará los puntos donde el círculo azul tocará ambos círculos rojos con mayor precisión que la iteración.

Sin embargo. hay varias condiciones en las que si solo haces esto, obtienes la respuesta incorrecta o no respondes. es decir.

1 o sin círculos

2 o más círculos pero con el punto objetivo lejos y fuera de ellos.

muchos círculos pero con un punto objetivo cerca de la superficie

Ewan
fuente
2
Que necesita hacer rodar el borde del círculo azul alrededor del exterior de los otros círculos es la parte fácil de resolver. La parte difícil es descubrir las ecuaciones / cálculos para hacerlo.
Robert Harvey
1
¿De Verdad? es solo (x-x1) ^ 2 + (y-y1) ^ 2 = (r + r1) ^ 2
Ewan
2
Y luego tienes que hacer todo eso nuevamente cuando intentes con el siguiente punto. Sé que el OP dijo que el rendimiento no era una preocupación, pero debe completarse antes de la muerte por calor del universo.
Robert Harvey
2
La única forma de saber si obtendrá diez votos a favor o no es publicar su código C # y ver qué sucede.
Robert Harvey
2
Lo que creo que sucederá es que el OP codificará esto como su respuesta de tarea y nunca más tendremos noticias suyas
Ewan
1

Este plunk contiene código de trabajo,

Concepto

Los círculos dados son C1, C2 ... Cn

y las coordenadas del círculo Cn es Cnx, Cny y el radio es Cr

y el radio del círculo requerido es R

si el círculo azul está en la ubicación X, Y y no entra en conflicto con ningún otro círculo, las siguientes ecuaciones son verdaderas

(C1x - X)^2 + (C1y - Y)^2 > (C1r + R)^2
(C2x - X)^2 + (C2y - Y)^2 > (C2r + R)^2
....
(Cnx - X)^2 + (Cny - Y)^2 > (Cnr + R)^2

cambiando la primera ecuación,

C1x^2 - 2C1x*X + X^2 + C1y^2 - 2C1y*Y + Y^2 > C1r^2 + 2C1r*R + R^2
X^2 + Y^2 - 2C1x*X - 2C1y*Y > C1r^2 + 2C1r*R + R^2 - C1x^2 - C1y^2

para que las ecuaciones puedan reescribirse como,

X^2 + Y^2 - 2C1x*X - 2C1y*Y > C1r^2 + 2C1r*R + R^2 - C1x^2 - C1y^2
X^2 + Y^2 - 2C2x*X - 2C2y*Y > C2r^2 + 2C2r*R + R^2 - C2x^2 - C2y^2
....
X^2 + Y^2 - 2Cnx*X - 2Cny*Y > Cnr^2 + 2Cnr*R + R^2 - Cnx^2 - Cny^2

Implementación

comenzar desde la coordenada del punto blanco (Xw, Yw),

    var isValidLocation = function(x,y,r){
       var valid = true;
       for (var i = 0; i< circles.length; i++){
          var circle = circles[i];
          valid = valid && ((x*x + y*y - 2*circle.x*x - 2*circle.y*y) > (circle.radius*circle.radius + 2*circle.radius*r + r*r - circle.x*circle.x - circle.y*circle.y));
       }
       return valid;
      };

      var find = function(Xw,Yw,Rw){
        var radius = 0;
        while(true){
          for (var x=-1 * radius ;x <= radius; x++) {
            for (var y=-1 * radius;y <= radius; y++) {
               if (isValidLocation(Xw + x,Yw + y, Rw)){
                 drawCircle(Xw + x,Yw + y,Rw,"#0000FF");
                 return;
               }
            }   
          } 
          radius++;
        }
     }; 

la primera coordenada encontrada para satisfacer todas las ecuaciones es la ubicación del círculo azul

Pelican de bajo vuelo
fuente
¿Alguien puede explicar qué hay de malo en este enfoque?
Low Flying Pelican
Eso es difícil de leer. Usa algunos buenos nombres y abstracciones. ¿Te mataría agregar un diagrama?
candied_orange
Hasta donde puedo ver, este enfoque trata de encontrar solo ubicaciones válidas para el círculo azul, pero no la ubicación más cercana posible. Esto podría solucionarse, sin embargo, el enfoque también hace la suposición (muy probablemente inválida) de que solo hay un número finito de coordenadas de valores enteros.
Doc Brown
Comienza desde la coordenada del punto blanco, y lo rodea expandiendo la cuadrícula de búsqueda. Debido a eso, no enfrentará ninguna situación en la que tenga un número infinito de coordenadas. Eventualmente encontrará coordenadas coincidentes.
Low Flying Pelican
1
... para una solución correcta en coordenadas enteras, debe usar un radio creciente y hacer que su espacio de búsqueda sea un círculo de este radio alrededor del punto blanco. Y aunque el OP escribió que la eficiencia no es su preocupación, sería una buena idea no probar cada par de coordenadas ya probado en cada bucle una y otra vez.
Doc Brown
0
  • O siendo el punto al que estás tratando de estar cerca
  • P es el punto que está buscando (el centro del círculo azul
  • r siendo el radio del círculo azul
  • C0 .. Cn son los centros de todos los círculos que restringen la colocación del azul en
  • círculo extendido es uno de los círculos con su radio extendido por r

    Hay algo de trabajo adicional si O no está en un centro circular. Así que ahora suponga que O == C0

Calcule todas las intersecciones de todos los círculos con C0, utilizando sus respectivos radios más la r , es decir, intersecte los círculos extendidos con el C0 extendido. Si no hay intersecciones, entonces el punto que está buscando está en cualquier lugar de C0, si hay intersecciones, para cada intersección verifique si está dentro de otro círculo extendido (puede limitarse a los círculos que tenían intersecciones con C0). Tome la primera intersección que no está en otro círculo extendido como P, puede haber otras.

Si no hay intersecciones entre los círculos extendidos y C0 que no están dentro de otro círculo extendido, calcule las intersecciones de todos los círculos extendidos entre sí. Luego verifique estas intersecciones en orden de distancia a O, nuevamente si alguna de las intersecciones se encuentra dentro de otro círculo extendido, si es así, descarte, si no, ese es su resultado.

Si imagina esto, imagine dibujar una línea alrededor de todos los círculos que indican una posible ubicación para su círculo azul, tomar la unión de todos los círculos extendidos indicará el área que su círculo azul no puede ser. El punto que está buscando es el punto más cercano que no está en esa unión. Si hay algún punto en C0 que no esté en esa unión, esa es la solución, si C0 está completamente cubierto, entonces P debe estar en una intersección entre otros dos círculos extendidos, y debe estar en un área que no esté cubierta por esta unión (es decir, no en un círculo extendido ).

Esto es O (n ^ 2), hay algunas formas de mejorar esto, sin embargo, se puede usar una cuadrícula para reducir el esfuerzo de la búsqueda por pares, también creo que ordenar los círculos por su cercanía a O, (la distancia entre dos círculos reducidos por la radio) ayudarían a limitar el espacio de búsqueda para la búsqueda de cobertura e intersección

Harald Scheirich
fuente
0

Posible búsqueda de soluciones

  1. Compruebe si el punto blanco es la solución por sí solo. Cubre el caso con 0 círculos rojos y el caso trivial cuando los círculos rojos están muy lejos del punto blanco.
  2. Un círculo rojo
    1. El punto blanco es el centro del círculo. Las posibles soluciones son un número infinito de puntos en el círculo con su centro en el punto blanco y el radio es la suma del radio de los círculos azules y el diámetro del círculo rojo. Llamémoslo el círculo verde .
    2. El punto blanco está en otro lugar. Solo hay una solución posible en la línea que conecta el punto blanco y el centro del círculo rojo, es el radio del círculo azul lejos del punto donde el círculo rojo cruza la línea hacia el punto blanco.
  3. Dos o más círculos rojos.
    1. Tomemos círculos rojos uno por uno y busquemos una posible solución para cada uno de ellos individualmente de acuerdo con el punto 2 (un círculo).
    2. Para cada par de círculos rojos, verifiquemos si puede dibujar el círculo azul tocando los dos rojos. Es decir, si la distancia entre sus centros es igual o menor que la suma de sus radios más el diámetro del círculo azul. Si puede, entonces tiene dos (o una si los círculos rojos están exactamente a un diámetro de círculo azul) posibles soluciones .

Búsqueda de soluciones reales entre posibles soluciones

Ahora tiene un conjunto de puntos que son posibles soluciones , repítalos y verifique cada uno.

  1. Si el punto es realmente una solución. Ningún círculo rojo debe tener su centro más cerca que su radio a este punto.
  2. Si está más cerca del punto blanco que la solución encontrada anteriormente.
  3. Si tiene el círculo verde (punto 2.1)
    • Si entre los puntos individuales no hay una solución que pertenezca al círculo verde, entonces el círculo verde es la respuesta.
    • Si tiene soluciones individuales en el círculo verde y necesita cualquier solución, simplemente tome una de ellas.
    • Si tiene soluciones individuales en el círculo verde y necesita toda la cantidad ilimitada de soluciones, entonces necesita resolver otro problema. Debe cortar del círculo verde todos los arcos definidos por un par de soluciones individuales de cada círculo rojo.

NB: No estoy diciendo que la implementación del algoritmo deba describirse exactamente. Puede intentar mejorar el rendimiento utilizando programación dinámica u omitiendo posibles soluciones donde es obvio que no funcionarán.

Vlad
fuente