Misurare la rettilineità di un segmento di curva (rappresentato come una polilinea)


11

Sto lavorando a un algoritmo di etichettatura automatica del profilo di elevazione e uno dei fattori che voglio prendere in considerazione quando decido le posizioni delle etichette è quanto "dritto" sia un particolare segmento di un contorno. Più è diritto, più è probabile che venga utilizzato per posizionare l'etichetta su quel segmento.

Ogni contorno è rappresentato da una polilinea (ma con punti ravvicinati da sembrare una curva ad occhio nudo). Ho quindi una lunghezza fissa (larghezza di un'etichetta), diciamo 100 pixel. Se scelgo casualmente (o altrimenti) un segmento di contorno con una larghezza di 100 pixel, voglio essere in grado di ottenere un valore quantitativo numerico della sua rettilineità (diciamo zero per un segmento di contorno totalmente dritto, un valore maggiore di zero per un non segmento così dritto e questo valore aumenta all'aumentare della storta).

Ho cercato le risposte ma non sono riuscito a trovare nulla di veramente utile. Sarei grato per qualsiasi suggerimento.

Risposte:


9

La risposta dipende dal contesto : se esaminerai solo un numero limitato (limitato) di segmenti, potresti essere in grado di permetterti una soluzione computazionalmente costosa. Tuttavia, sembra probabile che tu voglia incorporare questo calcolo all'interno di una sorta di ricerca di buoni punti etichetta. In tal caso, è di grande vantaggio disporre di una soluzione che sia o computazionalmente veloce o che consenta un rapido aggiornamento di una soluzione quando il segmento di linea candidato è leggermente variato.

Ad esempio, supponiamo che tu intenda condurre una ricerca sistematicaattraverso un intero componente collegato di un contorno, rappresentato come una sequenza di punti P (0), P (1), ..., P (n). Ciò si farebbe inizializzando un puntatore (indice nella sequenza) s = 0 ("s" per "inizio") e un altro puntatore f (per "fine") in modo che sia l'indice più piccolo per il quale distanza (P (f), P (s))> = 100, quindi avanzamento di s fino a quando distanza (P (f), P (s + 1))> = 100. Questo produce una polilinea candidata (P (s), P (s + 1) ..., P (f-1), P (f)) per la valutazione. Avendo valutato la sua "idoneità" per supportare un'etichetta, si aumenterebbe quindi s di 1 (s = s + 1) e si procederà ad aumentare f a (diciamo) f 'e s a s' fino a quando una polilinea candidata supera il minimo viene prodotto un intervallo di 100, rappresentato come (P (s '), ... P (f), P (f + 1), ..., P (f')). In tal modo, i vertici P (s) ... P (s ' È altamente desiderabile che la forma fisica possa essere rapidamente aggiornata dalla conoscenza dei soli vertici rilasciati e aggiunti. (Questa procedura di scansione continuerebbe fino a quando s = n; come al solito, f deve poter "avvolgere" da n indietro a 0 nel processo.)

Questa considerazione esclude molte possibili misure di idoneità ( sinuosità , tortuosità , ecc.) Che altrimenti potrebbero essere attraenti. Ci porta a favorire le misure basate su L2 , perché in genere possono essere aggiornate rapidamente quando i dati sottostanti cambiano leggermente. Prendendo un'analogia con l' analisi dei componenti principali si suggerisce di intrattenere la seguente misura (dove piccolo è meglio, come richiesto): utilizzare il più piccolo dei due autovalori della matrice di covarianzadelle coordinate del punto. Geometricamente, questa è una misura della "tipica" deviazione laterale dei vertici all'interno della sezione candidata della polilinea. (Un'interpretazione è che la sua radice quadrata è il semiasse più piccolo dell'ellisse che rappresenta i secondi momenti di inerzia dei vertici della polilinea.) Sarà uguale a zero solo per insiemi di vertici collineari; in caso contrario, supera lo zero. Misura una deviazione media da un lato all'altro rispetto alla linea di base di 100 pixel creata dall'inizio e dalla fine di una polilinea e quindi ha una semplice interpretazione.

Poiché la matrice di covarianza è solo 2 per 2, gli autovalori si trovano rapidamente risolvendo una singola equazione quadratica. Inoltre, la matrice di covarianza è una somma dei contributi di ciascuno dei vertici in una polilinea. Pertanto, viene rapidamente aggiornato quando i punti vengono eliminati o aggiunti, portando ad un algoritmo O (n) per un contorno n-point: questo si ridimensionerà bene ai contorni altamente dettagliati previsti nell'applicazione.

Ecco un esempio del risultato di questo algoritmo. I punti neri sono vertici di un contorno. La linea rossa continua è il miglior segmento polilinea candidato di lunghezza end-to-end maggiore di 100 all'interno di quel contorno. (Il candidato visivamente ovvio in alto a destra non è abbastanza lungo.)

figura


Wow, mi hai perso lì :). Hai ragione sulla ricerca sistematica, devo già farlo per ottenere la tangente di ciascun vertice polilinea / poligono (le etichette orizzontali sono preferite a quelle verticali), quindi in teoria potrei estendere questa ricerca per coprire altre misurazioni. A proposito: hai prodotto il diagramma di esempio usando un algoritmo reale o manualmente?
Igor Brejc,

1
L'illustrazione è reale, ma l'implementazione che ho usato non utilizza la procedura di aggiornamento della covarianza e quindi non è ottimale dal punto di vista computazionale.
whuber

2
Il grafico alla fine rende questa risposta ancora più fantastica
Ragi Yaser Burhum,

2
Igor, dovrei menzionare che la direzione dell'etichetta viene fornita gratuitamente: è data dalla direzione dell'asse maggiore dell'ellisse (l'autovettore associato all'autovalore maggiore). È quindi possibile cercare simultaneamente in modo efficiente la migliore combinazione di orientamento dell'etichetta e linearità della sezione del contorno.
whuber

3

Nella comunità di computer grafica, è spesso necessario trovare un rettangolo di selezione attorno a un oggetto. Di conseguenza, questo è un problema ben studiato, con algoritmi veloci. Ad esempio, vedi l' articolo sugli algoritmi del riquadro di delimitazione minimo di Wikipedia . È possibile trovare il rettangolo dell'area minima che circonda la polilinea, quindi utilizzare le proporzioni del rettangolo, altezza / lunghezza. Per ottenere una misura più precisa, è possibile osservare la deviazione della polilinea dalla linea centrale di questo rettangolo di delimitazione.


1
Ho pensato di usare min. delimitando i riquadri, ma vedo due problemi: a) complessità computazionale del calcolo di un riquadro che sarebbe davvero un minimo (e quindi ruotato), b) due segmenti di curva con le stesse proporzioni possono avere una curvatura molto diversa (si pensi a una sinusoidale curva con la stessa ampiezza ma periodi d'onda diversi).
Igor Brejc,

1
È bello vederti qui sulle pagine del GIS, Joseph!
whuber

1
Sì, ho il tuo libro "Geometria computazionale in C" nelle mie mani adesso :)
Igor Brejc,

1
Grazie per il benvenuto a tutti! :-) Mi rendo conto che il mio suggerimento non è la misura ideale, ma la codifica è standard (se hai lo scaffale giusto). Questo tipo di problema è stato studiato un po 'nei contesti produttivi, dove è necessario misurare la qualità di un pezzo lavorato.
Joseph O'Rourke,

3

Non so se questo aiuta, o anche se conta come una risposta, ma mentre ero seduto qui a pensare alla domanda che ho appena pubblicato, ho pensato:

Che cosa succede se si posiziona un cerchio di un raggio particolare sulla linea di contorno. Quel cerchio intersecherà la linea di contorno in almeno due punti. Più stretta è la linea, più breve è la distanza lungo la linea di contorno tra i due punti di intersezione. Maggiore è la distanza lungo la linea di contorno tra i punti di intersezione, più curva è la linea. Se ci sono più di due punti di intersezione, la linea di contorno è troppo curva.

Potresti capire quale lunghezza darebbe il miglior indicatore di rettilineità e impostare una routine per camminare lungo ogni linea di contorno e dove era abbastanza dritta, posizionare l'etichetta.

Sono sicuro che questo non aiuta molto, e quello che dico in inglese è molto più difficile in qualunque linguaggio di programmazione tu stia usando, ma potrebbe essere un inizio?


Idea interessante. Per renderlo più semplice, è possibile calcolare il rapporto tra la lunghezza del segmento su un lato e la distanza tra i punti iniziale e finale. Non è così preciso, ma è veloce da calcolare. E la tua idea di usare un cerchio consentirebbe un calcolo più preciso della rettilineità.
Igor Brejc,

3

L'approccio più semplice che mi viene in mente è il rapporto tra la lunghezza effettiva del percorso tra inizio e fine e la distanza più breve (linea retta) dall'inizio alla fine. Le linee rette avranno rapporti vicini a uno, mentre le linee molto curve avranno un rapporto molto elevato.

Questa dovrebbe essere una soluzione davvero semplice da implementare.


Aggiornamento: come Mike ha notato correttamente, questo equivarrebbe a Sinuosità .

inserisci qui la descrizione dell'immagine


Proprio quello che mi è venuto in mente dopo aver letto la risposta di Rex :)
Igor Brejc,

4
fondamentalmente il reciproco della sinuosità
Mike T

esattamente :) ....
underdark

2
Hai ragione sul fatto che sarebbe facile da implementare, perché aggiornare la lunghezza mentre si cercano i segmenti appropriati da etichettare è semplice come aggiungere e sottrarre lunghezze tra vertici successivi. Tuttavia, la sinuosità non cattura efficacemente il senso in cui una curva può discostarsi dalla linearità. Ad esempio, confronta un semicerchio di diametro 100 con una sequenza lineare di semicerchi di diametro 1 : entrambe le curve hanno la stessa sinuosità, ma la deviazione side-to-side del primo è 100 volte quella del secondo (che sarebbe una buona base per un'etichetta).
whuber

Tieni presente che se la tua polilinea traccia un cerchio questo metodo ti darà una sinuosità infinita che forse non è il risultato desiderato.
obchardon,

1

Cercando "curvatura" e "polilinea", ho ottenuto queste informazioni Come posso trovare la curvatura di una polilinea? . Lì ha suggerito di usare tornare alla definizione di curvatura - K= DF/Ds. Qui Fsignifica phi, o Tnella notazione di Wikipedia qui ( http://en.wikipedia.org/wiki/Curvature ).

Supponi di avere una sequenza di tre punti, p0, p1 e p2. calcola la distanza stra p0 e p1, che è delta di s ( Ds), supponendo che i punti siano abbastanza vicini l'uno all'altro. Quindi hai bisogno del delta di T ( DT), che è il cambiamento nel vettore tangenziale dell'unità tra p0 e p1. potrebbe esserci un modo sofisticato ma il metodo grezzo a cui riesco a pensare di prendere due bettori p0-> p1, p1-> p2, normalizzare ciascuno per avere una lunghezza di uno, quindi prendere la sottrazione vettoriale di quei due quindi determinare la grandezza. Questo è DT. La divisione produce una curvatura K0_1. prendi p1, p2 e p3 per calcolare K1_2e così via.

Mi chiedo però se si ottiene il contorno come una polilinea, non come pixel renderizzati. Hai detto 100px in modo da farmi preoccupare un po '.


Grazie per il link, dovrò studiare la matematica dietro di esso. Ho citato 100px semplicemente perché il testo dell'etichetta renderizzata ha una certa larghezza (in pixel), 100px era solo un esempio.
Igor Brejc,

Pensare alla curvatura è una bella idea. La curvatura attraverso sezioni di contorno fortemente levigate di lunghezza sufficiente potrebbe essere appropriata, ma la curvatura stessa non lo è: un singolo piccolo zig-zag avrebbe una curvatura estremamente elevata, ad esempio, ma sarebbe complessivamente insignificante. Pertanto, in effetti, utilizzeresti un riepilogo statistico della deviazione dalla linearità tra le sezioni della polilinea. Tra i probabili candidati, la curvatura sarebbe uno dei calcoli più complessi da eseguire.
whuber
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.