Comprobar la conexión entre dos puntos en el plano 2D


ASÍ QUE,

El problema

Tengo una pregunta sobre el algoritmo para determinar si dos puntos están conectados en el plano 2D. Tengo:

  • Matriz de líneas 2D. Cada línea está limitada con su punto de inicio final final 2D. Cada punto es una matriz simple de dos elementos [x,y] - es decir, cada línea se ve como ['start'=>[X0, Y0], 'end'=>[X1, Y1]] Deje que este conjunto de líneas se nombre como L. Las líneas pueden pertenecer una a otra (es decir, una podría ser parte de otra), pueden ser intersectadas por un solo punto e.t.c. - es decir, no hay restricciones para ellos en el plano 2D. Pero la línea no puede ser un punto - es decir, el comienzo de la línea no puede ser igual al final de la línea.
  • Dos puntos S y E, es decir, matrices [Xs, Ys] y [Xe, Ye]

Ahora, todas las líneas de L se dibujan en el plano. Entonces, S y E también se dibujan y necesito responder a la pregunta - ¿se puede llegar a E desde S sin intersección de líneas en L? Y, para ser más específicos, ¿qué algoritmo será óptimo? Por 'podría ser alcanzado' Quiero decir que hay un camino en el plano de S a E sin intersección ninguna línea de L - y, por causa, de esta manera podría ser cualquier cosa, no solo la línea.

Muestra

introduzca la descripción de la imagen aquí

-como ves, en la muestra S y E no están conectados. También en la muestra hay un caso cuando una línea pertenece completamente a otra (líneas grises y moradas) - y un caso cuando una línea tiene un inicio / final en otra línea (verde y rosa alinear).

Mi enfoque

Actualmente, tengo un algoritmo polinómico no determinista (NP) para hacer eso. Sus pasos son:

  • Encuentra todas las intersecciones para cada par de líneas.
  • Cree un nuevo conjunto de líneas a partir de los puntos del primer paso. Si dos líneas tienen una intersección, entonces habrá 4 nuevas líneas con el punto de intersección al comienzo de cada nueva línea - o puede ser 3 nuevas líneas si la primera línea tiene su inicio / final en la segunda línea-o puede ser 2 nuevo las líneas si la primera línea tiene su inicio/final coinciden exactamente con la línea de inicio/final de la segunda. I. e:

Cinco casos generales para dos líneas

Así que el caso 1-st resultará en 4 nuevas líneas, 2-4 casos en 3 nuevas líneas y 5 casos en 2 nuevas líneas. (las líneas son [A, B] y [C, D])

  • A continuación, en el paso lines del paso 2-nd estoy buscando todos los polígonos. Polígono es un conjunto de líneas cerradas (es decir, contiene una parte cerrada del área)
  • Estoy determinando para S subconjunto de tales polígonos que contienen S. A haga esto, estoy usando un algoritmo simple - contando el número de intersecciones con los bordes del polígono y alguna línea desde S al plano exterior (si es impar, entonces S está dentro del polígono y si es par - entonces afuera). Este es un algoritmo ray-casting. Entonces lo hago por E
  • Ahora, cuando tengo polígonos establecidos para S y E simplemente estoy comparando ambos conjuntos. Si son iguales, entonces E podría ser alcanzado desde S y no podría ser - de lo contrario.

¿por Qué es este NP?

La respuesta es simple: en el paso 3-rd estoy realizando una búsqueda de todos los bucles en 2D-graph. Dado que es un problema encontrar la longitud máxima / mínima del bucle si NP, entonces el mío también lo es (porque puedo obtener la longitud máxima/mínima del bucle simplemente ordenando los bucles resultantes). Buena información sobre esto se encuentra aquí .

La cuestión

Dado que mi solución actual es NP, quiero saber-puede ser mi solución para el problema es un exceso? Es decir, ¿puede haber una solución más simple que resultará en tiempo polinómico?

Author: Community, 2013-09-27

5 answers

Básicamente el problema se reduce a:
1) Determinar todos los polígonos que encierran algún espacio que no contiene ningún otro polígono. En el ejemplo anterior, tiene 3 formas/ciclos/polígonos que no contienen otras: el cuadrilátero que contiene S, el cuadrilátero que contiene E y el triángulo debajo del 2 de ellos.
2) Determinar si S y E están en opuesto dentro / fuera de cualquiera de estos polígonos.

Para la parte 1, tienes que construir un gráfico:

Crear un matriz de puntos de intersección de su línea dada, esto es N^2. Recuerde de qué 2 líneas vino cada punto de intersección. Estos puntos de intersección son los vértices de su gráfico.

Dos vértices están "conectados" si son de la misma línea y no hay otro punto de intersección entre ellos. No confíe en la precisión del punto flotante para determinar esto, obviamente.

Ahora desea encontrar los polígonos en su diseño. Un gráfico puede, en general, contener un número exponencial de ciclos. Sin embargo, cada arista solo puede bordear 2 polígonos "internos", por lo que solo estamos interesados en un subconjunto polinómico de los ciclos. Así que elige una arista, luego encuentra la siguiente arista en el polígono, y sigue repitiendo hasta que vuelvas a donde empezaste o determines que la primera arista no era parte de un polígono.

Así que supongamos que viene de la arista E = (U, V), y desea encontrar la siguiente arista en el polígono (compartiendo el mismo vértice V).
1) Crear un vector T como U - V.
2) Crear el conjunto de aristas A que son adyacentes al vértice V. Eliminar E de ese conjunto.
3) Si el conjunto está vacío, entonces el borde no es parte de un polígono.
4) Para cada arista (Q, V) en A, construir un vector R como Q - V. (Recuerde Q y V representan puntos en el plano 2D).
5) Normalizar R: divídalo por su longitud para crear un vector de longitud 1.
6) Determinar el valor del producto cruzado (T, R).
7) El borde en A con el menor CrossProductValue es el siguiente borde en uno de los polígonos adyacentes. El borde en Un con el mayor CrossProductValue es el siguiente borde en el otro polígono.

CrossProductChecker(2D T, 2D R) {
  return (T.x*R.y - T.y*R.x); // cross product for 2 dimensions
}

Así que usa esto para encontrar tus polígonos. Busca la relación entre los productos cruzados y los sinusoides para tener una idea de cómo funciona esto.

============

Ahora que tienes todos tus polígonos, todo lo que hay que hacer es comprobar si hay uno que S está dentro y E está fuera, o al revés.

La manera fácil de hacer esto es dibujar una línea de S a E. Si se cruza con cualquier polígono (ciclo desde arriba) un número par de veces, ambos están dentro o ambos fuera del polígono, así que sigue comprobando.

Si la línea interseca un ciclo un número impar de veces, entonces uno está dentro del polígono y el otro está fuera, por lo que se puede decir que no hay camino.

 9
Author: DanielV,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-27 11:35:17

Puede construir un llamado "Gráfico de visibilidad" que conecta dos vértices de obstáculos si son directamente visibles. El camino más corto en este gráfico (con S y E añadidos) será el camino sin obstáculos más corto entre S y E en su espacio de configuración. Los algoritmos y optimizaciones relativos al Gráfico de visibilidad son bien conocidos y ampliamente descritos.

La principal dificultad que tendrá es manejar casos de esquina para que no pueda "filtrar" en alguna intersección incorrecta hacia el otro lado del segmento (segmentos compartidos, punto final como intersección, etc.). Manejar estos casos de esquina no es algorítmicamente difícil, pero requiere paciencia.

EDITAR:

Así que permítanme ser más formal: construir un gráfico G(Ver, Edg) donde Ver contiene todos los extremos del segmento, S y E; y Edg contiene todos los pares de vértices que son directamente visibles (incluyendo después del segmento).

 6
Author: goldwin-es,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-17 23:30:35

Hay dos pasos para el algoritmo.

1. Find out the maximum polyogn encompassing S and E 
    (which could possibly be an open polygon, so convex hull algorithm needs 
    to be modified)
2. E can be reached from S if
    (Case 1) The polygons are the same
    (Case 2) Both are open polygons.

Explicación:

Paso 1: Encuentre el polígono que abarca máximo de un punto P

Form a set of points by adding the end-points and all possible 
    intersections. (O(n^2))
Eliminate points that can only be reached from P by crossing another line. 
    This can be done by finding the intersection of the line joining P to each 
    point with all other lines (O (n^3)).
Form a convex hull of the remaining points. 
    Here it should be noted that the resulting polygon may not be closed. 
    So, the convex hull algorithm needs to be modified to get rid of 
    those possible edges which don't have a direct connection. 
    This can be efficiently done by an appropriate data structure 
    like a graph (O(n^2) in worst case)

Paso 2: La comparación necesitaría algún tipo de ordenación de los vértices de los polígonos. Esto sería máximo O (n largo n)

Así que la complejidad del algoritmo resultante sería O (n^3)

Ver el diagrama

 4
Author: PermanentGuest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-27 15:18:54

Calcule el gráfico plano de línea recta formado por los segmentos de línea y localice las caras a las que pertenecen S y E. Hay un camino si y solo si S y E pertenecen a la misma cara. Los dos primeros pasos son algoritmos de tiempo polinómico estándar de geometría computacional, con muchas descripciones e implementaciones disponibles.

 2
Author: David Eisenstat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-27 17:38:13
  1. buscar todas las intersecciones entre segmentos de línea
  2. elimine todos los puntos que tienen rango = 1; es decir, es un punto final, solo un segmento de línea está conectado a este punto
  3. encuentra el segmento de línea más cercano al punto S
  4. buscar polígono cuyo lado se encuentra previamente segmento de línea, utilizando el siguiente enfoque:
    1. se da el segmento de la línea de salida
    2. marca ambos extremos del segmento inicial, starting = lsS, ending = lsE
    3. buscar todos los segmentos de línea conectados a lsE, excluido el segmento inicial
    4. de los segmentos encontrados elija el segmento que está más cerca del punto S la línea más cercana es la que, cuyo centro es posible conectar con el punto S sin intersecar ninguna de las líneas examinadas
    5. elimine todos los demás segmentos de línea examinados del espacio problema
    6. repita hasta que tenga polígono completo
  5. si el polígono completo contiene ambos puntos E y S, estos están conectados

Es un poco similar a la profundidad primero búsqueda.

Muy mala ilustración de mi idea.

En cada paso solo se trabaja con vecinos inmediatos del último punto resuelto con éxito.

 2
Author: jnovacho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-17 23:28:34