¿Cuál es la forma más eficiente de encontrar el grosor mínimo de pared (valor y ubicación) de un área compleja de polígono no convexo que incluye agujeros? Vea el ejemplo de un polígono en azul, con el mínimo espesor de pared en rojo, aunque en este caso la ubicación es ambigua, si las dos líneas adyacentes son paralelas.
Hasta ahora, hemos intentado:
- Subdividir líneas de polígono y encontrar líneas de punto mínimo dentro del polígono (fuerza bruta, no eficiente para polígonos complejos con> 10'000 puntos)
- Delaunay triangulación y encontrar bordes mínimos dentro del polígono. No es lo suficientemente preciso, solo factible si se combina primero con la subdivisión de líneas poligonales. Aquí está el ejemplo (Nr 3), donde la triangulación de Delaunay no encontraría bordes simples en rojo pero se perdería el mínimo espesor de pared en el cuadro verde:
- Aumento iterativo del tampón de erosión para encontrar la inserción mínima, donde el polígono de erosión se rompe en varias partes = la mitad del espesor mínimo de la pared. El problema es encontrar la ubicación del espesor de pared mínimo con este enfoque después. Además, la erosión no siempre se rompe en múltiples partes y pierde "callejones sin salida". Aquí hay un ejemplo (Nr 2) que se erosiona en una línea y da el grosor de pared mínimo incorrecto:
- Primero encuentre el eje medial, luego busque el círculo mínimo en el eje medial que cubre pero no superpone el área del polígono. Editar: problemáticos son los muchos "candidatos equivocados" en el eje medial: por ejemplo. (Nr 1) el círculo A estaría mal, el círculo B indicaría el grosor mínimo correcto de la pared:
Respuestas:
Uno de los métodos más eficientes para encontrar el espesor mínimo de pared (valor y ubicación) de un área de polígono compleja y no convexa que incluye agujeros, podría ser mediante el uso de una capa regularmente espaciada (o aleatoria) de puntos para determinar, primero, el segmento más cercano con contexto para cada punto y, luego, el punto de intersección entre el segmento incremental y el polígono del lado opuesto; basado en directores cosenos.
Las distancias incrementales se pueden usar hasta que el primer segmento alcance e intersecte algún polígono lateral (el grosor mínimo de la pared).
Para probar mi enfoque, cloné su polígono con agujeros y creé una capa de puntos aleatorios dentro del polígono con 100 puntos; como se puede observar en la siguiente imagen:
El código usado de PyQGIS tiene el siguiente aspecto:
y produce una capa de memoria de distancias incrementales (solo para fines de visualización) e imprime un grosor de pared mínimo en formato WKT.
Después de ejecutar el código en Python Console de QGIS obtuve el resultado de la siguiente imagen:
Se puede observar que solo una distancia incremental alcanzó primero el lado opuesto en el área esperada.
El formato WKT impreso (para un grosor de pared mínimo) se usa con el complemento QuickWKT de QGIS para visualizar ese segmento en la siguiente imagen:
La ligera inclinación se produjo porque el "segmento más cercano con el contexto" se unió a un vértice; en cambio lado polígono. Sin embargo, se puede evitar con una excepción de código o más puntos.
fuente
Dos ideas más para tirar en la olla:
Rasterice su polígono y use una transformación de distancia (devuelve la imagen de la distancia más corta desde cada píxel distinto de cero a un píxel cero). Esqueletice su imagen rasterizada, luego tome los valores de la imagen transformada a lo largo del esqueleto. De ese conjunto tendrá algunos mínimos que deberían corresponder a su ancho más estrecho. Este conjunto se puede utilizar como puntos de búsqueda iniciales para luego implementar su enfoque de fuerza bruta. Debo señalar que el esqueleto bisecará las esquinas de los objetos, y en esos lugares la transformación de distancia se acercará a cero (a medida que te acerques al límite del objeto). Esto puede ser problemático, pero representa un problema con su problema: ¿por qué puede ' ¿El ancho más pequeño estará en una esquina (y será esencialmente cero)? Puede resolver este problema estableciendo un umbral en la distancia más corta alrededor del perímetro entre los dos puntos (si se encuentran en el mismo objeto). Puede usar una transformación de distancia geodésica en el conjunto de píxeles del perímetro para encontrar rápidamente ese valor.
Este método requiere que tome una decisión sobre la resolución del polígono rasterizado, que introduce cierta dependencia de escala. Y si elige una resolución demasiado alta, la transformación de distancia puede llevar mucho tiempo. Pero en general son bastante rápidos. Es posible que este método no le brinde la precisión que desea, pero al menos podría brindarle un conjunto mucho más pequeño de ubicaciones que deben verificarse.
Su método de fuerza bruta no es un mal lugar para comenzar. Tuve un problema similar cuando tuve que encontrar todas las intersecciones de una línea (larga) consigo mismo, y pude acelerar enormemente el tiempo de búsqueda usando un algoritmo de búsqueda de árbol kd (usé rangesearch en Matlab en ese momento) para encontrar puntos dentro de un barrio primero. De esa manera, solo estás forzando a un bruto un pequeño subconjunto del número total de puntos.
fuente
El enfoque del eje medial es correcto, solo necesita un criterio para ignorar los círculos incorrectos: cada círculo en el eje medial toca la superficie en dos (o más) puntos. Imagine vectores desde el centro del círculo hasta estos puntos en la superficie y observe que el ángulo intermedio es 180 ° para el círculo bueno B y solo 90 ° para el círculo malo A.
fuente
Un algoritmo genérico de dibujo poligonal funciona ordenando los segmentos de línea de arriba a abajo y trabajando a través de ellos para dibujar líneas ortogonales de píxeles. Como esta forma de descomponer polígonos (sin curvaturas) es muy rápida, puede usarse como base. En lugar de ir solo de arriba a abajo, puede ir a 0, 30, 60 y 90 grados, y encontrar su sección ortogonal más corta (= ¡espesor de pared mínimo!), Solo tiene que calcular eso una vez por punto y no para cualquier tipo de 'resolución de píxeles'.
Ver computer-graphics-scan-line-polygon-fill-Algoritmo
fuente