Draw perpendicular line of fixed length at a point of another line

If slope is the slope of AB, then the slope of CD is -1/slope. This is equal to vertical change over horizontal change: dy/dx = -1/slope. This gives that dx = -slope*dx. And by Pythagorean Theorem, you have 3**2 = dy**2+dx**2. Substitute for dx, and you get

3**2 = (-slope*dy)**2+dy**2
3**2 = (slope**2 + 1)*dy**2
dy**2 = 3**2/(slope**2+1)
dy = math.sqrt(3**2/(slope**2+1))

Then you can get dx = -slope*dy. Finally, you can use dx and dy to get C and D. So the code would be:

import math
dy = math.sqrt(3**2/(slope**2+1))
dx = -slope*dy
C[0] = B[0] + dx
C[1] = B[1] + dy
D[0] = B[0] - dx
D[1] = B[1] - dy

(Note that although math.sqrt returns only one number, in general there is a positive and negative square root. C corresponds to the positive square root, and D to the negative).


Since you are interested in using Shapely, the easiest way to get the perpendicular line that I can think of, is to use parallel_offset method to get two parallel lines to AB, and connect their endpoints:

from shapely.geometry import LineString

a = (10, 20)
b = (15, 30)
cd_length = 6

ab = LineString([a, b])
left = ab.parallel_offset(cd_length / 2, 'left')
right = ab.parallel_offset(cd_length / 2, 'right')
c = left.boundary[1]
d = right.boundary[0]  # note the different orientation for right offset
cd = LineString([c, d])

enter image description here

And the coordinates of CD:

>>> c.x, c.y
(12.316718427000252, 31.341640786499873)
>>> d.x, d.y
(17.683281572999746, 28.658359213500127)