2012-06-11 22 views
13

Estoy tratando de determinar la distancia de un punto a un polígono en el espacio 2D. El punto puede estar dentro o fuera del polígono; El polígono puede ser convexo o cóncavo.Distancia de un punto a un polígono

Si el punto está dentro del polígono o fuera del polígono con una distancia menor que una constante definida por el usuario d, el procedimiento debe devolver True; False de lo contrario.

He encontrado una pregunta similar: Distance from a point to a polyhedron or to a polygon. Sin embargo, el espacio es 2D en mi caso y el polígono puede ser cóncavo, por lo que es de alguna manera diferente de ese.

Supongo que debe haber un método más simple que compensar el polígono por d y determinar si está dentro o fuera del polígono.

Algún algoritmo, código o indirectas para mí para googlear sería apreciado.

+1

¿El código de llamada necesita saber la distancia, o simplemente si está dentro de una cierta distancia? –

+0

Encontré esto para ti. Devuelve la distancia real de punto a polígono (positivo si el punto está fuera del polígono y negativo de lo contrario). Es código de Matlab, pero puede ser útil desde una perspectiva algorítmica: http://www.mathworks.com/matlabcentral/fileexchange/19398-distance-from-a-point-to-polygon/content/p_poly_dist.m –

+2

@KendallFrey solo si está dentro de una cierta distancia. Sin embargo, ¿sería posible determinar si está dentro de una cierta distancia sin saber exactamente cuál es la distancia? – clwen

Respuesta

15

Su mejor opción es recorrer todas las líneas y encontrar la distancia mínima de un punto a un segmento de línea.

para encontrar la distancia de un punto a un segmento de línea, primero se encuentre la distancia de un punto a una línea seleccionando puntos arbitrarios P1 y P2 en la línea (que podría ser una buena idea usar sus puntos finales). A continuación, tome el vector de P1 a su punto P0 y encuentre (P2-P1) . (P0 - P1) donde . es el producto escalar. Divida este valor por ||P0-P1||^2 y obtenga un valor r.

Ahora bien, si usted escogió P1 y P2 como sus puntos, sólo tiene que comprobar si r es entre 0 y 1. Si r es mayor que 1, entonces P2 es el punto más cercano, por lo que su distancia es ||P0-P2||. Si r es menor que 0, entonces P1 es el punto más cercano, por lo que su distancia es ||P0-P1||.

Si 0<r<1, a continuación, su distancia es sqrt(||P0-P1||^2 - r * ||P2-P1||^2)

El pseudocódigo es el siguiente:

for p1, p2 in vertices: 

    var r = dotProduct(vector(p2 - p1), vector(x - p1)) 
    //x is the point you're looking for 

    r /= magnitude(vector(x - p1)) 

    if r < 0: 
    var dist = magnitude(vector(x - p1)) 
    else if r > 1: 
    dist = magnitude(vector(p2 - x)) 
    else: 
    dist = sqrt(magnitude(vector(x - p1))^2 - r * magnitude(vector(p2-p1))^2) 

    minDist = min(dist,minDist) 
+1

Esto es lo que también pienso. Esta respuesta SO se refiere a encontrar la distancia más corta entre un punto y un segmento de línea: http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment. – hatchet

+0

¿Hay algún algo disponible para eso? –

+0

@Muneem Actualicé mi respuesta para obtener un pseudocódigo fácil de entender al final. –

2

Si tiene una función de distancia de segmento punto a línea, puede usarla para calcular la distancia desde el punto a cada uno de los bordes del polígono. Por supuesto, debes verificar si el punto está dentro del polígono primero.

2

¿Necesita rápida o sencilla?
¿Tiene que ser siempre absolutamente correcto en las cajas de borde o lo suficientemente bueno la mayoría de las veces está bien?

La solución típica es encontrar la distancia a cada vértice y encontrar el par con los valores más pequeños (tenga en cuenta que para un punto fuera de un polígono convexo estos pueden no ser adyacentes) y luego controlar las intersecciones de punto a línea para cada segmento.

Para formas complejas grandes también puede almacenar cajas de polígono delimitadoras (rectangulares o hexágonos) y encontrar el lado más cercano antes de consultar más detalles.

Es posible que también necesite un código para manejar el caso especial de exactamente en una línea.

+0

Considera el ejemplo extremo de un polígono triangular con dos vértices muy distantes del punto objetivo, pero con la línea entre ellos pasando muy cerca del punto objetivo. El tercer vértice del triángulo está a una corta distancia más allá de esa línea. Un atajo que solo examina las líneas conectadas a ese vértice más cercano producirá la respuesta incorrecta. – hatchet

+2

@hatchet, sí, es por eso que dije que debes considerar el uso. Una rutina de detección de colisión en un juego es diferente de la navegación y una línea costera fractal es diferente de una aplicación CFD. –

+0

I programa de juegos, este algoritmo parece no válido para cualquier aplicación en la que no se garantiza que los bordes del polígono sean de la misma longitud. – SongWithoutWords

0

Te puedo ayudar con esto punteros:

  • La distancia puede ser calculada usando Wikipedia entry, incluso con una cortada con tijeras sin probar de código.
  • El interior/borde exterior puede ser resuelto con este Stack Post and links

y algunas observaciones:

  • debe comprobar sólo los puntos más próximos, como Martin Beckett salidas puntuales respuesta, ya que otro segmento se puede "proyectar" muy cerca, pero en realidad no se está cerca de la necesidad.
+0

Para el problema del borde interior/exterior, no estoy comparando solo con rectángulos, sino con polígonos generales. Encontré el comentario en el enlace que diste ayuda. ¡Gracias! – clwen

-2

puede hacer su programa de correr un poco más rápido mediante el uso de la trigonometría y la sentencia pecado

+0

¿dónde se usa el pecado? La oración de pecado no se usa para ese problema, o si luego se detalla más. – AlexWien

+0

Esta es una receta excelente para ralentizar significativamente su programa y posiblemente perder algo de precisión en su camino. – Michael

Cuestiones relacionadas