2012-02-16 10 views
5

Tengo una colección de Rectos de tamaño n, la mayoría de los cuales se cruzan entre sí. Me gustaría eliminar las intersecciones y reducir los Rect intersección en rects más pequeños que no se cruzan.Buscando un algoritmo que no sea "fuerza bruta" para eliminar las áreas que se cruzan de una colección de Rectos

Podría forzar fácilmente una solución bruta, pero estoy buscando un algoritmo eficiente.

Aquí es una visualización:

original:

original

Procesado:

processed

Lo ideal sería que la firma del método se vería así:

public static List<RectF> resolveIntersection(List<RectF> rects); 

la salida sería mayor o igual que la entrada, donde la salida resuelve la representación visual anterior.

+0

¿Cuál es el pensamiento para el rectángulo rojo que reclama espacio que podría haber sido reclamado por los rectángulos verde o naranja (haciéndolos más largos ...)? –

+0

Arranqué arbitrariamente ese rectángulo. –

+0

Resulta que esto es realmente lo que quería: http://google-maps-utility-library-v3.googlecode.com/svn/trunk/routeboxer/docs/examples.html Probablemente debería haber pedido una solución al problema real en lugar de una solución al problema que creé en el medio de mi implementación. –

Respuesta

2

este es un problema que he resuelto en el pasado. Lo primero es ordenar los rectángulos usando el valor x o y de uno de los bordes. Digamos que ordena en la dirección y y utiliza el borde superior. El rectángulo superior en su ejemplo es primero en orden ordenado. Para cada rectángulo, conoce su tamaño en la dirección y.

Ahora, para cada entrada (llámala la entrada actual, corresponde a un rectángulo) en la lista ordenada que buscas en la lista hasta llegar a una entrada mayor que la entrada actual + el tamaño del rectángulo correspondiente. (llámelo la entrada de detención)

Cualquier entrada en la lista ordenada entre la entrada actual y esta entrada de parada serán posibles intersecciones. Simplemente verifica si los rectángulos X-Rangos se cruzan.

Al elegir ordenar en la dirección xo y, será mejor elegir la dimensión que sea más grande ya que esto implicará una menor intersección en promedio, por lo tanto, menos control.

Aquí hay un ejemplo. Los rectángulos se definen como R (x1, x2, y1, y2), donde x1 es el lado izquierdo, x2 es lado derecho, y1 es superior y y2 es inferior

rectangle 1 (1,5,0,4) 
rectangle 2 (7,9,6,8) 
rectangle 3 (2,4,2,3) 
rectangle 4 (3,6,3,7) 
rectangle 5 (3,6,9,15) 

tipo de acuerdo con y1 para dar

#    y1 size 
rectangle 1  0 4 
rectangle 3  2 3 
rectangle 4  3 4 
rectangle 2  6 2 
rectangle 5  9 6 

, el rectángulo 1 tiene y1 + tamaño = 0 + 4 = 4 lo que implica que potencialmente intersectará el rectángulo 3 (valor y1 = 3 < 4) y el rectángulo 4 (valor y1 = 3 < 4) pero no el rectángulo 2 (valor y1 = 6> 4) ... no hay necesidad de verificar ningún rectangels en la lista después de 2

Rectángulo 3 tiene y2 + tamaño = 2 + 3 = 5 lo que implica que potencialmente intersecará el rectángulo 4 (valor y1 = 3 < 5) pero no recanallar 2 (valor y1 = 6> 5) no es necesario verificar ningún rectangels en la lista después de 2

Rectángulo 4 tiene y2 + tamaño = 3 + 4 = 7 lo que implica que potencialmente intersecará el rectángulo 2 (valor y1 = 6 < 7) pero no volverá a conectar 5 (valor y1 = 9> 7)

Por supuesto, con un gran número de rectángulos generalmente solo tendrá que verificar una fracción de los pares posibles para la intersección.

+0

una mejora: para decidir qué dimensión utilizar para la ordenación, puede ver el rango de valores en esa dimensión dividido por el tamaño promedio del rectángulo en esa dimensión En el ejemplo anterior, el tamaño y medio es 19/5 mientras que el tamaño promedio x es 15/5, por lo que esperaría (sin otro conocimiento) que estas sean más intersecciones en la dirección y (los tamaños rectangulares y son más grandes en promedio que los tamaños x así que hay más posibilidades de que se crucen). Esta elección puede marcar una gran diferencia si estás mirando miles de rectángulos. – martino

-2

lo que estás descrbing es el problema de embalaje, echar un vistazo a wikipedia

se refiere a this artículo que describe un algoritmo para rectángulos de embalaje en rectángulos

se trata del artículo de:

Este artículo describe un algoritmo rápido para empaquetar una serie de rectángulos de diferentes anchuras y alturas en un único rectángulo delimitador, sin superposición y de una manera que minimiza la cantidad de espacio desperdiciado en el rectángulo circundante .

+3

¿Estás seguro? ¿Cómo se rompen los rectángulos superpuestos en no superposición más pequeña mediante el uso de embalaje rectangular? Me parece que la solución podría basarse en el algoritmo de línea de barrido en su lugar: http://en.wikipedia.org/wiki/Sweep_line_algorithm. – Timo

+0

@Timo es una variación del problema de embalaje, he agregado las primeras líneas de la introducción. – yurib

+0

@Timo, aunque nunca había escuchado sobre el algoritmo de línea de barrido, por lo que he leído parece interesante, también podría ser un buen enfoque. – yurib

6

Los algoritmos Sweepline son buenos para procesar intersecciones en universos 2D. Me refiero a considerar una línea horizontal que se mueve desde un borde rectangular al borde del rectángulo siguiente. La línea golpea una cantidad de rectángulos, formando las llamadas listas activas. La lista activa se mantiene actualizada en cada movimiento.

Al estudiar los rangos de abscisas a lo largo de la línea horizontal, puede detectar las superposiciones.

Un estudio cuidadoso de todas las configuraciones debería permitirle dividir los rectángulos de la forma que desee en un solo barrido, con menor complejidad que la fuerza bruta (más cerca de N^1.5 que de N^2).

+0

Esto es probablemente marginalmente más eficiente que el forzado bruto en el ejemplo anterior, pero creo que es lo mejor que podré hacer. Gracias. –

+1

Se sabe que el problema de intersección de rectángulo se puede resolver en el tiempo óptimo O (N Log (N) + K), donde K es el número real de intersecciones, por ejemplo, utilizando árboles de intervalos. Alternativamente al barrido de línea, se han publicado algoritmos de dividir y conquistar. –

+1

Esto es apetecible: http://www.springerlink.com/content/r161n73q01067x1p/ –

Cuestiones relacionadas