8 votos

Cómo crear cuerdas de líneas con un ángulo y una longitud definidos, que están fijadas a un punto

Quiero crear cordeles con un ángulo (por ejemplo, 160°) y una longitud (por ejemplo, 2m) definidos que se fijen en una serie de puntos de otro cordel. Por lo tanto, quiero usar la función ST_DumpPoints para encontrar los puntos y unir los cordones creados a ellos. ¿Hay alguna manera de declarar un ángulo (α) durante la creación de la cuerda de línea? Aquí hay una imagen de ejemplo:

enter image description here

Quiero crear las líneas azules.

EDITAR

El ángulo (α2) en la imagen no es realmente ejemplar. Sino más bien un acimut de 160° (como α1).

ACTUALIZACIÓN

La respuesta del Genio Malvado me ayudó a calcular el ancho máximo de un polígono con un aspecto determinado.

11voto

David Holm Puntos 6165

Esto se puede lograr de diferentes maneras, dependiendo del tipo de resultado que se desee, pero el concepto es el mismo. Por lo general, es más fácil hacer una simple rotación seguida de una traslación que intentar calcular las coordenadas en un solo paso.

En este caso, los pasos básicos son:

  • Crea una línea de la longitud deseada en el origen (0,0). Esta línea debe correr a lo largo del eje desde el que desea medir su ángulo y tener su centro en el origen.
  • Rota la línea alrededor del origen.
  • Traslada la línea por las coordenadas del punto en el que quieres que esté centrada.

La siguiente vista de PostGIS crea las líneas de su escenario de ejemplo. Se asumen algunas cosas:

  • La columna de geometría se llama shape
  • El ángulo se mide desde el eje x. Tu dibujo de ejemplo era un poco confuso ya que primero mencionaste 40 grados, dibujaste una línea vertical punteada, pero luego dijiste que debería ser alrededor de 160 grados. He interpretado eso como que en realidad quieres medir desde el eje x.
  • Los datos se proyectan en las mismas unidades con las que se quiere medir (es decir, metros).

    CREATE OR REPLACE VIEW <viewname> AS
    WITH vertices AS
    (SELECT 
          objectid, 
          (ST_DumpPoints(shape)).path[1] AS v_id, 
          (ST_DumpPoints(shape)).geom AS vertex
    FROM <source_data>
    )
    SELECT
        objectid,
        v_id,
        ST_SetSRID(ST_Translate(ST_Rotate(ST_MakeLine(ST_MakePoint( 1.0,0.0), 
                                                      ST_MakePoint(-1.0,0.0)),
                                          radians(40)), ST_X(vertex), ST_Y(Vertex)),
                                          ST_SRID(vertex)) AS newline
    FROM vertices

Para desglosar lo que realmente sucede con esa última línea, empezando por lo más interno: ST_SetSRID(ST_Translate(ST_Rotate(ST_MakeLine(ST_MakePoint( 0,1.0), ST_MakePoint(0,-1.0)), radians(40)), ST_X(vertex), ST_Y(Vertex)), ST_SRID(vertex)) AS newline

  • ST_MakePoint(1.0,0.0) y ST_MakePoint(-1.0,0.0) : Crea los puntos extremos de una línea horizontal que tenga la longitud deseada y esté centrada en el origen.
  • ST_MakeLine(...) : Utiliza nuestros puntos finales recién creados para crear una línea.
  • ST_Rotate(..., radians(40)) : Rota esa nueva línea alrededor del origen.
  • ST_Translate(..., ST_X(vertex), ST_Y(vertex)) : Centra la línea rotada en nuestro punto de referencia (de entrada).
  • ST_SetSRID(..., ST_SRID(vertex)) : Dar a la nueva línea el mismo SRID que la geometría de entrada.

Si está utilizando PostGIS 2.0 puede simplificar esto ya que puede especificar un origen diferente para ST_Rotate . Si quieres rotar a un ángulo basado en la pendiente de la línea, tendrás que calcularlo primero y añadirlo al ángulo de rotación.

Si los datos no se proyectan en las mismas unidades en las que quieres medir, puedes hacer algo similar, pero necesitarás un paso adicional:

  • Cree una línea (proyectada en algo que utilice lo que quiere medir)
  • Girar
  • Reproyectar a su proyección de destino
  • Trasladar al punto de destino

Editar

Ahora entiendo lo que quieres decir con lo del ángulo. Esencialmente, quieres una rotación en el sentido de las agujas del reloj desde el eje Y (0 es arriba, 90 es derecha, 180 es abajo, etc.).

Todavía tiene que utilizar el radians función desde ST_Rotate espera el ángulo en radianes. Deberías ser capaz de obtener el ángulo correcto con dos pequeños cambios:

  • Comience con una línea vertical (utilice ST_MakePoint(0.0,1.0) y ST_MakePoint(0.0,-1.0) )
  • Multiplica tu ángulo por -1. Esto lo hará negativo, causando ST_rotate para girarlo en el sentido de las agujas del reloj. radians(<angle> * -1)

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X