# Draw a normal from a point to a line

How to draw a normal LineString (AB) to existing LineString (CDEF) from a given Point (A)?

Shapely version == 1.5.16

Here's a method that will extend the line if required (see boxes in example screenshots) to guarantee a 90 degree angle. It is based on the following answer which contains full details of the working.

Projection of a point to a line segment Python Shapely

``````import numpy as np
from shapely.geometry import Point, LineString

points = [Point(4.5, 1.5), Point(4.5, 1.5), Point(1.95, 2.35), Point(11.78, -1.38), Point(9.32, -0.02), Point(0.95, 0.94)]
line = LineString(((0.5, 0.0), (2.5, 1.0), (7.0, 1.25), (10, -2.0)))

# Explode line segments
lines = []
for c1, c2 in zip(line.coords, line.coords[1:]):
lines.append(LineString([c1, c2]))

for point in points:
# get closest line segment
distances = [segment.distance(point) for segment in lines]
nearest_line = lines[distances.index(min(distances))]

x = np.array(point.coords[0])

u = np.array(nearest_line.coords[0])
v = np.array(nearest_line.coords[len(nearest_line.coords) - 1])

n = v - u
n /= np.linalg.norm(n, 2)

p = u + n * np.dot(x - u, n)

l = LineString([point, Point(p)])

# If you want to see which actually intersect
# if l.intersects(nearest_line.buffer(1e-05)):  # Use buffer to handle floating point imprecision
# do something...
``````

I have 2 layers: a point layer, a line layer.

1/I explode the line (see qgis menu) so as to be able to select each segment of the polyline.

2/ from the pt layer, from the geometry command by expression (see qgis menu) I write the following line:

`shortest_line(\$geometry, aggregate('Explose', 'collect', \$geometry))`

• This doesn't guarantee 90 degrees. E.g. imagine if the top-most polyline were tilted at 45 degrees instead of approximately flat, as you've shown.
– Jon
Commented Jul 10, 2022 at 1:00