Cómo saber si dos polígonos dados se cruzan / se superponen

Al responder a esta pregunta de JavaScript Point Collision with Regular Hexagon en Stackoverflow, en mi mente, formé un algoritmo que estoy bastante seguro de que es muy eficiente para aplicaciones tan complicadas.

Es simplemente una cuestión de representar el polígono como una sola función. Una función de [math] \ theta [/ math] en este caso.

Ingrese la transformación discreta de Fourier .

No sé si esto se ha implementado antes (conozco los descriptores de Fourier) pero es bastante sencillo no solo para un polígono convexo o cóncavo regular. Todavía no lo he puesto en código ya que tengo algunas otras cosas como prioridad en mi mente en este momento. Alguien conoce un enfoque similar, por favor hágamelo saber.

OK … ¿Qué representa el polígono como una función única de [math] \ theta [/ math]? Una idea podría ser dibujar los polígonos en el plano complejo de modo que cada vértice del polígono esté representado por un número complejo como 3 + 4i en lugar de las coordenadas x e y (3,4).

Por ejemplo, en la siguiente figura, el polígono rojo tiene 6 vértices básicos como [matemática] 3 + 4i [/ matemática], [matemática] -2 + 3i [/ matemática], [matemática] -1 + i [/ matemática], [ matemática] -3-i [/ matemática], [matemática] 2–2i [/ matemática], [matemática] 1 + i [/ matemática] mientras que la verde tiene 4 vértices principales como [matemática] 2 + 3i [/ matemática ], [matemáticas] -2 + 2i [/ matemáticas], [matemáticas] -4-i [/ matemáticas], [matemáticas] -2-3i [/ matemáticas].

Lo que haremos es representar estos polígonos como datos de series de tiempo mediante la recopilación de los vértices de forma ordenada en sentido antihorario y aplicar FFT (Transformada rápida de Fourier) para cada polígono. Para FFT necesitamos datos [matemáticos] 2 ^ n [/ matemáticos] (vértices aquí). Entonces, por simplicidad, usemos solo 16 vértices por polígono. (Si usamos más como 32 o incluso 64, se separarán de manera más uniforme y se obtendrá una representación más precisa de nuestro polígono en el dominio de la frecuencia). Así que solo calcule vértices adicionales usando trigonometría simple. Nuestra figura es ahora la siguiente;

Entonces, como puede ver, tenemos 16 vértices para el rojo a partir de [matemática] 1.33 + 0i [/ matemática] en sentido antihorario y 16 vértices para el verde a partir de [matemática] 0 + 0i [/ matemática] en sentido antihorario.

Entonces, FFT nos dará [matemática] n [/ matemática] muchos (0–15) coeficientes complejos que se multiplicarán por los [matemáticos] \ cos (n \ theta) + i \ sin (n \ theta) [/ matemáticos] correspondientes función. La suma de estas 16 funciones nos dará la función del polígono en la variable [math] \ theta [/ math]. Una cosa a tener en cuenta es que, dado que tenemos datos complejos, los 16 coeficientes resultantes deben interpretarse de la siguiente manera; (Primero, el componente DC como [math] 0 \ theta [/ math]) y luego [math] \ theta [/ math], [math] 2 \ theta [/ math], [math] 3 \ theta [ / matemática], [matemática] 4 \ theta [/ matemática], [matemática] 5 \ theta [/ matemática], [matemática] 6 \ theta [/ matemática], [matemática] 7 \ theta [/ matemática], [matemática ] 8 \ theta [/ math] (Nyquist), [math] -7 \ theta [/ math], [math] -6 \ theta [/ math], [math] -5 \ theta [/ math], [math ] -4 \ theta [/ math], [math] -3 \ theta [/ math], [math] -2 \ theta [/ math], [math] – \ theta [/ math].

Entonces, solo para dar una idea, he transferido el polígono rojo al dominio de frecuencia y ahora es una sola función de fase. Por supuesto, ya que solo hemos tomado 16 muestras y aunque todos los vértices están perfectamente cubiertos, todavía es una pequeña papa. 32 muestras producirían una aproximación mucho mejor. Sin embargo, incluso con esta forma, puede hacer una buena detección de colisión.

Entonces, una vez que representamos cada polígono como una función de [math] \ theta [/ math], todo lo que necesitamos es escanear a lo largo de sus bordes en sus lados más cercanos. También en este punto me gustaría mencionar que el componente DC de la representación de Fourier de cada polígono es, de hecho, las coordenadas de sus centroides. Esta es una información gratuita (como en cerveza gratis) pero valiosa para que nuestro algoritmo funcione. Ok vamos a dibujar y mostrar el polígono verde en “papa” también junto con sus centroides.

Ahora podemos calcular que el ángulo entre los dos centroides es [matemática] 0.422 [/ matemática] radianes y, en consecuencia, podemos escanear el polígono rojo comenzando desde [matemática] \ pi + 0.422–0.5 [/ matemática] a [matemática] \ pi + 0.422 + 0.5 [/ matemáticas] radianes y el verde a partir de [matemáticas] 0.422 + 0.5 [/ matemáticas] a [matemáticas] 0.422–0.5 [/ matemáticas] radianes y verifique si los puntos correspondientes en los polígonos rojo y verde son en el orden de los centroides (como el verde a la izquierda y el rojo a la derecha) Un único punto de contradicción revelará una colisión. En este caso particular, todos los puntos en el rango de exploración son contradictorios.

La belleza de este enfoque es

  • Una vez que transforma sus polígonos en dominio de frecuencia, no necesita repetir esta cosa FFT nunca. Moverlos significa solo alterar el componente DC. Todo lo que necesita es hacer controles en un rango estrecho cada vez que uno de ellos o ambos se muevan.
  • Se puede aplicar fácilmente a formas muy complejas.
  • La eficiencia de este algoritmo se puede aumentar al reducir el rango de escaneo. Esto reducirá drásticamente el número de operaciones. También puede reducir la resolución de los ángulos de escaneo como puede hacer solo uno por [math] \ frac {\ pi} {45} [/ math] en lugar de [math] \ frac {\ pi} {180} [/ math ], o incluso para menos escaneos alrededor del lado relacionado del polígono. Tan genial ..! Gracias señor Fourier.

1. Primero encuentre si hay una intersección entre los bordes de los dos polígonos.
2. Si no es así, elija cualquier punto del primer polígono y pruebe si está completamente dentro del segundo.
3. Si no es así, elija cualquier punto del segundo polígono y pruebe si está completamente dentro del primero.
4. Si no, puede concluir que los dos polígonos están completamente fuera del otro.

Para el n. ° 1, use cuadros delimitadores para seleccionar las regiones que se probarán. Si los polígonos son realmente enormes, también podría usarse algún tipo de árbol de jerarquía espacial.

Incluso hay una solución más simple para este problema que la respuesta de Makarand Apte a esta pregunta:

Encuentre el área del polígono 1. (Área 1)
Encuentre el área del polígono 2. (Área 2)
Encuentra el área de configuración dada. (Área 3)

Si: | Área3 | <| Área1 | + | Área2 |
Entonces: ambos polígonos se superponen

De lo contrario: no ..

Esta sería la solución requerida con baja complejidad algorítmica de tiempo.
¡Gracias!

Desde un punto de vista práctico, puede usar algunas heurísticas para evitar cálculos largos.

Supongamos que solo tiene polígonos convexos, P1 y P2

  • Primera prueba de cajas delimitadoras. Si los cuadros delimitadores no se superponen, no se superponen
  • Ordenar todas las coordenadas Y y las coordenadas X y escanearlas. Si no hay un punto de P1 con puntos de P2 a ambos lados, en las matrices X e Y, entonces no se superponen
  • Finalmente, puede probar cada borde de P1 contra cada borde de P2 y, si alguno se cruza, se superponen. Probablemente puedas usar alguna información del paso anterior para evitar probar cada borde

En caso de proyección ortográfica se da. Dibuje la vista de borde de uno de los polígonos y también dibuje el segundo polígono en ese plano. Si también se cruzan en esta vista. Luego se cruzan polígonos.

Utilice SAT (Teorema del eje de separación) , muy simple y directo.