Estoy tratando de averiguar los puntos de inflexión, es decir, los puntos donde comienzan y terminan las curvas en una línea. Si observa la imagen, la línea verde puede ser una carretera o una corriente, y los puntos negros son los puntos donde comienzan y terminan las curvas.
¿Cuáles serían los pasos de alto nivel para automatizar la generación de estos puntos? Tengo el escritorio ArcGIS y soy bastante útil con ArcObjects.
arcobjects
algorithm
Devdatta Tengshe
fuente
fuente
Respuestas:
Cuando la curva se compone de segmentos de línea, todos los puntos interiores de esos segmentos son puntos de inflexión, lo que no es interesante. En cambio, la curva debe considerarse aproximada por los vértices de esos segmentos. Al dividir una curva por partes dos veces diferenciable a través de esos segmentos, podemos calcular la curvatura. Un punto de inflexión, estrictamente hablando, es un lugar donde la curvatura es cero.
En el ejemplo, hay tramos largos donde la curvatura es casi cero. Esto sugiere que los puntos indicados deberían aproximarse a los extremos de tales tramos de regiones de baja curvatura.
Por lo tanto, un algoritmo eficaz dividirá los vértices, calculará la curvatura a lo largo de un conjunto denso de puntos intermedios, identificará rangos de curvatura cercana a cero (utilizando una estimación razonable de lo que significa estar "cerca") y marcará los puntos finales de esos rangos .
Aquí hay un
R
código de trabajo para ilustrar estas ideas. Comencemos con una cadena de línea expresada como una secuencia de coordenadas:Spline las coordenadas x e y por separado para lograr una parametrización de la curva. (Se llamará al parámetro
time
).Interpolar las splines para el trazado y el cálculo:
Necesitamos una función para calcular la curvatura de una curva parametrizada. Necesita estimar la primera y segunda derivada de la spline. Con muchas splines (como splines cúbicas), este es un cálculo algebraico fácil.
R
proporciona los primeros tres derivados automáticamente. (En otros entornos, uno podría querer calcular las derivadas numéricamente).Propongo estimar un umbral para la curvatura cero en términos de la extensión de la curva. Este al menos es un buen punto de partida; debe ajustarse de acuerdo con la tortuosidad de la curva (es decir, aumentada para curvas más largas). Esto luego se usará para colorear las parcelas de acuerdo con la curvatura.
Ahora que los vértices se han dividido y se ha calculado la curvatura, solo queda encontrar los puntos de inflexión . Para mostrarlos, podemos trazar los vértices, trazar la spline y marcar los puntos de inflexión en ella.
Los puntos abiertos son los vértices originales
xy
y los puntos negros son los puntos de inflexión identificados automáticamente con este algoritmo. Debido a que la curvatura no puede calcularse de manera confiable en los puntos finales de la curva, esos puntos no están especialmente marcados.fuente
Puede usar la herramienta Densificar . Para este caso, elige densificar por ángulo. Luego, elija el ángulo máximo aceptado en una línea recta. Luego aplique a la línea de resultado a la herramienta Dividir línea en vértices . Finalmente, elimine las líneas que tienen shape_length más pequeñas que la longitud mínima del camino.
En esta imagen, vemos tres pasos:
1- Densificar la línea usando el ángulo. He usado 10 grados como parámetro, y usamos splitline. En la imagen, la línea curva está en su fase inicial.
2- Seleccione los segmentos donde tener shape_length no sea redundante. Como vemos en la tabla, no he seleccionado esas longitudes redundantes. Luego, los selecciono en una nueva clase de entidad.
3- Hemos extraído los vértices ubicados en los bordes de las líneas, que son puntos de inflexión.
fuente
Puede utilizar la herramienta Generalizar que tiene el desplazamiento máximo de la línea original como parámetro, por lo que puede elegir el desplazamiento que se ajuste a su caso.
Si nombramos la línea original "line_cur" y la generalizada "line_gen", podríamos recortar "line_cur" por "line_gen". El resultado será el segmento recto de "line_cur". Luego podríamos limpiar algunos segmentos muy cortos eliminándolos con una consulta sql que selecciona Shape_length mayor que la longitud mínima del camino.
fuente