Domanda

Ho bisogno di "fit", un GraphicsPath arbitrariamente forma in uno spazio definito (quasi sempre un rettangolo o un cerchio).

Attualmente scala GraphicsPath utilizzando l'oggetto Matrix e il ridimensionamento funziona bene, ma il problema sta ottenendo i fattori di scala.

La tecnica migliore che posso venire in mente è la conversione del GraphicsPath ad una regione, la conversione del rettangolo o un cerchio ad una Regione, e l'esecuzione di una:

rgnShape.Intersect(rgnCircle);

e quindi verificare se:

rgnShape.IsEmpty()

Tuttavia, questo solo mi dice che se la forma è troppo grande per forma, e si rende necessario per scalare la forma più piccola, e riprovare (forse molte, molte volte).

C'è un modo semplice per calcolare all'istante i fattori di scala per adattarsi a un GraphicsPath poligono in modo che si adatti completamente in un cerchio. Il risultato dovrebbe essere il più grande poligono che si adatta ancora del tutto all'interno del cerchio.

È stato utile?

Soluzione

http://en.wikipedia.org/wiki/Smallest_circle_problem per la discussione di questa problema in termini di punti, piuttosto che percorsi, trovato da Simon.

  1. Quindi, fare questo, l'uso rgnShape.Intersect(rgnCircle); per verificare se ha funzionato. Se non è riuscito, prendere ogni curva e afferrare i punti più lontani dal centro del cerchio che hai trovato (ci possono essere più di uno di tali punti per ogni regione).

  2. Aggiungi loro di elencare riapplicare l'algoritmo di tuoi punti. Non avrete bisogno di ripartire da zero; non è necessario prendere in considerazione i punti non sul confine (vale a dire, ignorano i punti non in "Set Q" che è stato trovato dalla chiamata originale per l'algoritmo).

Si noti che questo non è più lineare, poiché la probabilità di generare chiamate ricorsive è più 1 / i per il punto esimo.

Questa è una condizione bordo è necessario gestire in modo esplicito. Nel caso in cui una delle curve trovato trovato fuori della regione trovato durante la prima iterazione della fase 1 è perfettamente circolare e toccando il cerchio esterno, ci saranno infiniti punti all'interno "Set Q" e questo algoritmo sicuro sprecando. Così, dopo l'applicazione rgnShape.Intersect(rgnCircle); per la prima volta, si dovrebbe verificare eventuali curve perfettamente rotonde esplicitamente per questo caso. Ad esempio, se la forma è (} si dovrebbe verificare in modo esplicito () (per fini di questa discussione, () finta è un cerchio) se si trova ( al di fuori della regione hanno trovato durante la prima iterazione.

Questo è ancora piuttosto male, ma è meglio che cambiare tutti Curva in punti.

Altri suggerimenti

Non vedo il motivo per cui è necessario il binario di ricerca.

Una volta che si ottiene il rettangolo di delimitazione per la tua forma, e si ha il rettangolo di destinazione in cui si desidera per adattarsi alla forma, è possibile confrontare i due rapporti targetHeight / shapeHeight e targetWidth / shapeWidth.

Prendere il rapporto più piccolo, e utilizzare questo come il fattore di scala per scalare la forma.

Se il bersaglio è un cerchio e non un rettangolo, è possibile utilizzare una soluzione simile prendendo il rapporto tra targetCircleDiameter / boundingRectangleDiagonal e utilizzare questo come fattore di scala.

Si potrebbe usare GetBounds sul GraphicsPath e la Regione, quindi confrontare le dimensioni dei rettangoli per ottenere almeno si chiude.

Se lo spazio definito è una piazza che dovrebbe essere esatto.

Se lo spazio definito qualcos'altro, che sarebbe ottenere almeno si chiude. È quindi possibile utilizzare una ricerca binaria per trovare l'importo effettivo ridimensionamento.

Non puoi calcolare il centro del GraphicsPath e un raggio?

Si potrebbe centro o di calcolo di gravità (media di coordinate) e aggiungere 2 volte deviazione standard - questo dovrebbe farti circa il 92% del grafico - la maggior parte del tempo sarebbe bene, ma non riuscirà se il grafico ha più 'peso' in una delle estremità.

Si potrebbe anche calcolare il centro dei punti - corsa attraverso tutti i punti, ricevere / min punti massimi in tutte le direzioni come quando si calcola BoundingBox, prendere il centro di questo e di misurare la distanza più lunga per i punti (max / min) come raggio .

Si potrebbe probabilmente trovare un algoritmo più sofisticato se cercate un algoritmo di sfera di delimitazione - ma se è solo alla visualizzazione qualcosa che si potrebbe fare un po 'compromessi. Se stai facendo il rilevamento delle collisioni esiste alcuni algoritmi veloci anche per questo :)

Come circa andando nella direzione opposta utilizzando la matematica semplice? Cioè ottenere la delimitazione scatola / cerchio del percorso, calcolare il rapporto rettangolare predefinito di altezza / larghezza, confrontare che allo stesso valore di BB, allungare il BB conseguenza (ad esempio se razione predefinito è inferiore a 1, il BB è allungata orizzontalmente e verticalmente altrimenti per abbinare lo stesso rapporto), per poi scalare il tutto alla dimensione rettangolare predefinita. Il fattore di scala è ora solo il minimo tra altezza predefinita diviso altezza BB e predefiniti larghezza divisa per la larghezza BB. (Per il cerchio di delimitazione non v'è alcuna necessità di regolare le dimensioni.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top