5

I found this code but it requires both first and second point to create a line. How can I change it so it works with only first point, length of the line, and an angle?

from shapely.geometry import LineString
from shapely.geometry import Point

p = Point(5,5)
c = p.buffer(3).boundary
l = LineString([(0,0), (10, 10)])
i = c.intersection(l)

print i.geoms[0].coords[0]
(2.8786796564403576, 2.8786796564403576)

print i.geoms[1].coords[0]
(7.121320343559642, 7.121320343559642)
Georgy
  • 12,464
  • 7
  • 65
  • 73
user15636383
  • 51
  • 1
  • 2
  • Shapely doesn't support infinite lines. If you want to construct a LineString of finite length, just a point and an angle is not enough. We need also information about the length of the LineString, or the x or y coordinate of the second point. – Georgy Apr 14 '21 at 22:25
  • Calculate the second point at distance `L` with angle `Fi`: `x2 = x1 + L * cos(Fi) y2 = y1 + L * sin(Fi)` – MBo Apr 15 '21 at 04:49
  • @Georgy i have length too, could you tell me how to do it? – user15636383 Apr 15 '21 at 16:44

1 Answers1

8

You have several options:

  1. Calculate the coordinates of the second point using basic trigonometry:
    import math
    from shapely.geometry import LineString, Point
    
    start = Point(0, 0)
    length = 1
    angle = math.pi / 3
    
    end = Point(start.x + length * math.cos(angle),
                start.y + length * math.sin(angle))
    line = LineString([start, end])
    print(line)
    # LINESTRING (0 0, 0.5000000000000001 0.8660254037844386)
    
    If your angle is not in radians but in degrees, you should convert it first:
    angle = 60
    angle = math.radians(angle)
    
  1. Make a horizontal line with the given start point and length, and then rotate it by given angle around the first point:

    from shapely.affinity import rotate
    from shapely.geometry import LineString, Point
    
    start = Point(0, 0)
    length = 1
    angle = math.pi / 3
    
    end = Point(start.x + length, start.y)
    line = LineString([start, end])
    line = rotate(line, angle, origin=start, use_radians=True)
    print(line)
    # LINESTRING (0 0, 0.5000000000000001 0.8660254037844386)
    

    Note that by default rotate function expects angles in degrees, so if we want to pass an angle in radians to it, we have to use the use_radians=True as shown above.

    Alternatively, we could also use translate function to get the endpoint:

    from shapely.affinity import translate
    end = translate(start, length)
    
Georgy
  • 12,464
  • 7
  • 65
  • 73