2012-01-27 13 views
8

Ho una soluzione che utilizza dati spaziali per rappresentare un cluster di punti su una mappa. Ho bisogno di usare le coordinate che rappresentano le estensioni di un cluster per trovare il rettangolo di limitazione minimo che può contenere detto gruppo di punti.Calcolo del rettangolo di delimitazione minima della forma 2D per coordinate

Esiste un semplice algoritmo per poter calcolare questo o esiste una funzionalità incorporata in C# per ottenere ciò. Sono a conoscenza di NetTopologySuite ma non sono sicuro di come/se potrei usarlo per raggiungere lo stesso obiettivo. Ho una lista di coordinate quindi dovrei passare questa lista di stringhe e ottenere l'MBR.

+0

Purtroppo non ho idea da dove cominciare con questo problema. Sono nella fase in cui ho le mie coordinate in una lista di stringhe di caratteri e sono incerto su come procedere da qui. – CSharpened

+1

@Bene ci sono due tipi: il riquadro di delimitazione allineato all'asse; che si trova semplicemente trovando il min x/y e il massimo x/y. O hai il bounding box arbitrariamente orientato che è più complicato (http://en.wikipedia.org/wiki/Minimum_bounding_box_algorithms). Questo è reso più complicato se devi tener conto della curvatura della terra (che spero non lo fai), anche se tecnicamente stai ancora disegnando una scatola, ma in realtà è una sezione della superficie di una sfera (probabilmente troppo per quello che ti serve) –

+0

Vedo. Ho bisogno di una funzione che fornisca 4 coordinate per la scatola. Quindi i due valori X e i due valori Y. Suggeriresti che il modo migliore per farlo sarebbe dividere le mie coordinate e poi confrontarle tutte per trovare il valore X più basso e il valore Y minimo? Se dovessi farlo, suppongo che otterrei solo un valore minX e un valore maxY?Da quelle due cifre è possibile calcolare gli altri valori X e Y? Scusa se mi sembra un po 'perso. Spaziale non è affatto la mia area. – CSharpened

risposta

10

La soluzione più semplice, e presumo quella che è più probabile che stiate cercando, consiste nel calcolare il riquadro di delimitazione allineato all'asse, che è semplicemente il caso di trovare i valori min/max x & y, quindi costruendo una scatola da quelli.

ti darò pseudo-codice per questo, dato che non avete pubblicato i tipi che la geometria è espresso in ...

type point { float x; float y; } 
type box { point topleft; point topright; point bottomleft; point 

function bounding_box(points) 
{ 
    xmin = min(points.x) 
    xmax = max(points.x) 
    ymin = min(points.y) 
    ymax = max(points.y) 

    return new box{ 
    topleft = { x = xmin, y = ymax }, 
    topright = { x = xmax, y = ymax }, 
    bottomleft = { x = xmin, y = ymin }, 
    bottomright = { x = xmax, y = ymin } 
    }; 
} 

Quindi, dato questi:

point[] points = [[x = -2, y = 0], [x = 1, y = 2], [x = 1, y = 1], [x = -1, y = -2]]; 
box bounds = bounding_box(points); 

Tutti i seguenti sarà vero:

bounds.topleft == [x = -2, y = 2]; 
bounds.topright == [x = 1, y = 2]; 
bounds.bottomleft == [x = -2, y = -2]; 
bounds.bottomright == [x = -1, y = -2]; 

Naturalmente, se il sistema di coordinate ha le coordinate bassi al t op (ad es. come un tipico display) - quindi è necessario invertire il calcolo; o calcola prima il risultato nello spazio-oggetto e poi traduci nello spazio logico in seguito.

Avviso Sono andato per un tipo per la casella che esprime tutti i quattro angoli, nel caso in cui si decida in futuro di aggiornare ad una casella arbitrariamente allineata in futuro (anche se per lo stesso token si potrebbe semplicemente usare un punto + 2 vettori per quello).

+0

Sembra esattamente quello che sto cercando. Grazie. – CSharpened

6

Una possibile, anche se semplice, modo per farlo potrebbe essere simile a questo:

public Rectangle Test(List<Point> points) 
{ 
    // Add checks here, if necessary, to make sure that points is not null, 
    // and that it contains at least one (or perhaps two?) elements 

    var minX = points.Min(p => p.X); 
    var minY = points.Min(p => p.Y); 
    var maxX = points.Max(p => p.X); 
    var maxY = points.Max(p => p.Y); 

    return new Rectangle(new Point(minX, minY), new Size(maxX-minX, maxY-minY)); 
} 

Questo ha ovviamente scontato che siete alla ricerca di un rettangolo che è allineato verticalmente che orizzontalmente. Quindi se stai cercando il rettangolo più piccolo possibile, non importa come viene ruotato, questo non fa per te.

Problemi correlati