2012-01-27 40 views
8

Tengo una solución que utiliza datos espaciales para representar un grupo de puntos en un mapa. Tengo la necesidad de utilizar las coordenadas que representan las extensiones de un clúster para encontrar el rectángulo delimitador mínimo que puede contener dicho grupo de puntos.Calcular rectángulo mínimo delimitador de forma 2D por coordenadas

¿Existe algún algoritmo simple para poder calcular esto o hay alguna funcionalidad incorporada en C# para lograr esto? Soy consciente de NetTopologySuite pero no estoy seguro de cómo/si podría usar esto para lograr el mismo objetivo. Tengo una lista de coordenadas, así que necesitaría pasar esta lista de cadenas y sacar el MBR.

+0

Lamentablemente no tengo idea de por dónde empezar con este problema. Estoy en la etapa en la que tengo mis coordenadas en una lista de tipo cadena y no estoy seguro de cómo continuar desde aquí. – CSharpened

+1

@ Bueno, tiene dos tipos: el cuadro delimitador alineado con el eje; que se encuentra simplemente al encontrar el min x/y el max x/y. O bien, tiene el cuadro delimitador orientado arbitrariamente, que es más complicado (http://en.wikipedia.org/wiki/Minimum_bounding_box_algorithms). Esto se hace más complicado si necesitas tener en cuenta la curvatura de la tierra (que espero que no lo hagas), aunque técnicamente todavía estás dibujando una caja, pero en realidad es una sección de la superficie de una esfera (probablemente demasiado para lo que necesita) –

+0

Ya veo. Necesito una función que proporcione 4 coordenadas para la caja. Entonces los dos valores X y los dos valores Y. ¿Sugeriría que la mejor manera de hacerlo sería dividir mis coordenadas y luego compararlas todas para encontrar el valor X más bajo y el valor mínimo Y? Si tuviera que hacer eso, ¿supongo que solo obtendría un valor minX y un valor maxY?¿De esas dos figuras es posible calcular los otros valores X e Y? Lo siento si parezco un poco perdido. Spatial no es mi área en absoluto. – CSharpened

Respuesta

10

La solución más fácil, y supongo que la que es más probable que esté buscando, es calcular el cuadro delimitador alineado con el eje, que es simplemente el caso de encontrar los valores mín/máx x & y, luego construyendo una caja de esos.

les daré pseudo-código para que, teniendo en cuenta que usted no ha publicado los tipos que su geometría se expresa en ...

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 } 
    }; 
} 

Así Dadas estas:

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

Todo lo siguiente será cierto:

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

por supuesto, si el sistema de coordenadas tiene las coordenadas más bajas en el t op (p. ej. como una pantalla típica) - entonces tiene que invertir el cálculo; o calcule el resultado en el espacio del objeto primero y luego traduzca al espacio lógico después.

Aviso He elegido un tipo para la caja que expresa las cuatro esquinas, en caso de que decida en el futuro actualizar a una caja arbitrariamente alineada en el futuro (aunque de la misma manera podría simplemente usar un punto + 2 vectores para eso).

+0

Eso se ve exactamente lo que estoy buscando. Gracias. – CSharpened

6

Una posible, aunque simple, forma de hacerlo podría ser así:

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)); 
} 

Esto hace, por supuesto, a suponer que usted está buscando un rectángulo que está alineado verticalmente y horizontalmente. Entonces, si está buscando el rectángulo más pequeño posible, sin importar cómo se gire, no es para usted.

Cuestiones relacionadas