2012-06-11 31 views
13

Sto provando a determinare la distanza da un punto a un poligono nello spazio 2D. Il punto può essere all'interno o all'esterno del poligono; Il poligono può essere convesso o concavo.Distanza da un punto a un poligono

Se il punto si trova all'interno del poligono o all'esterno del poligono con una distanza inferiore a una costante definita dall'utente d, la procedura deve restituire True; False altrimenti.

Ho trovato una domanda simile: Distance from a point to a polyhedron or to a polygon. Tuttavia, lo spazio è 2D nel mio caso e il poligono può essere concavo, quindi è in qualche modo diverso da quello.

Suppongo che ci dovrebbe essere un metodo più semplice che compensare il poligono di d e determinarlo all'interno o all'esterno del poligono.

Qualsiasi algoritmo, codice o suggerimenti per me per google in giro sarebbe apprezzato.

+1

Fa il codice chiamante ha bisogno di conoscere la distanza, o semplicemente se si tratta entro una certa distanza? –

+0

Ho trovato questo per te. Restituisce la distanza effettiva dal punto al poligono (positivo se il punto è al di fuori del poligono e negativo altrimenti). È un codice Matlab ma può essere utile da una prospettiva algoritmica: http://www.mathworks.com/matlabcentral/fileexchange/19398-distance-from-a-point-to-polygon/content/p_poly_dist.m –

+2

@KendallFrey solo se è all'interno di una certa distanza. Tuttavia, sarebbe possibile determinare se si trova entro una certa distanza senza sapere esattamente quale sia la distanza? – clwen

risposta

15

La soluzione migliore è iterare su tutte le linee e trovare la distanza minima da un punto a un segmento di linea.

per trovare la distanza da un punto ad un segmento di linea, per la prima volta la distanza esatta da un punto ad una linea con la scelta di punti arbitrari P1 e P2 sulla linea (potrebbe essere saggio di utilizzare gli endpoint). Quindi prendi il vettore da P1 al punto P0 e trova (P2-P1) . (P0 - P1) dove . è il prodotto punto. Dividere questo valore per ||P0-P1||^2 e ottenere un valore r.

Ora, se hai scelto P1 e P2 come i punti, si può semplicemente controllare se r è compreso tra 0 e 1. Se r è maggiore di 1, quindi P2 è il punto più vicino, quindi la distanza è ||P0-P2||. Se r è minore di 0, quindi P1 è il punto più vicino, quindi la distanza è ||P0-P1||.

Se 0<r<1, quindi la distanza è sqrt(||P0-P1||^2 - r * ||P2-P1||^2)

Lo pseudocodice è la seguente:

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

Questo è ciò che penso anch'io. Questa risposta SO parla della ricerca della distanza più breve tra un punto e un segmento di linea: http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment. – hatchet

+0

c'è qualche algo disponibile per questo? –

+0

@Muneem Ho aggiornato la mia risposta per uno pseudocodice di facile comprensione alla fine. –

2

Se si dispone di un punto di lavoro per la funzione di distanza del segmento di linea, è possibile utilizzarlo per calcolare la distanza dal punto a ciascuno dei bordi del poligono. Ovviamente, devi prima controllare se il punto è all'interno del poligono.

2

Avete bisogno veloce o semplice?
Deve essere sempre assolutamente corretto nei casi limite o sarà abbastanza buono per la maggior parte del tempo essere OK?

soluzione Tipici sono per trovare la distanza di ciascun vertice e trovare la coppia con i valori minimi (si noti che per un punto esterno di un poligono convesso questi potrebbero non essere adiacenti) e quindi controllare scegliere linea intersezioni per ogni segmento.

Per forme complesse di grandi dimensioni è anche possibile memorizzare circa caselle di delimitazione del poligono (rettangolari o esagoni) e trovare il lato più vicino prima di controllare più dettagli.

Potrebbe anche essere necessario il codice per gestire il caso speciale esattamente di una linea.

+0

Considera l'esempio estremo di un poligono triangolare con due vertici molto distanti dal punto di mira, ma con la linea che li divide molto vicino al punto di destinazione. Il terzo vertice del triangolo è solo una breve distanza oltre quella linea. Una scorciatoia che esamina solo le linee collegate a quel vertice più vicino produrrà la risposta sbagliata. – hatchet

+2

@hatchet, sì è per questo che ho detto che è necessario considerare l'uso. Una routine di rilevamento delle collisioni in un gioco è diversa dalla navigazione e una linea costiera frattale è diversa da un'applicazione CFD. –

+0

I giochi di programmazione, questo algoritmo sembra non valido per qualsiasi applicazione in cui non è garantito che i bordi del poligono siano della stessa lunghezza. – SongWithoutWords

0

ti posso aiutare con questo puntatori:

  • La distanza può essere calcolata utilizzando Wikipedia entry, anche con uno snipped testata di codice.
  • L'interno/bordo esterno può essere risolto con questa Stack Post and links

e alcune osservazioni:

  • si dovrebbe verificare solo i punti più vicini, come Martin Beckett's out point risposta, dal momento che un altro segmento può "essere proiettato" molto vicino, ma in realtà non è vicino al bisogno.
+0

Per il problema del bordo interno/esterno, non sto confrontando solo i rettangoli, ma i poligoni generali. Ho trovato il commento nel link che hai dato aiuti però. Grazie! – clwen

-2

potete fare il vostro programma di eseguire un po 'più veloce utilizzando la trigonometria e la condanna del peccato

+0

dove si usa il peccato? La frase del peccato non è usata per quel problema, o se poi si elabora ulteriormente. – AlexWien

+0

Questa è un'eccellente prescrizione per rallentare in modo significativo il tuo programma e perdere una certa precisione sulla tua strada. – Michael

Problemi correlati