Skip to content

Instantly share code, notes, and snippets.

@signed0
Created February 5, 2012 01:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save signed0/1741823 to your computer and use it in GitHub Desktop.
Save signed0/1741823 to your computer and use it in GitHub Desktop.
Cut a linestring at a distance
from math import sqrt
def cut(coords, distance):
'''Splits a cartesian linestring at a given distance
Returns None for either part if the length is 0
'''
if distance <= 0:
return None, list(tuple(j) for j in coords)
i = iter(coords)
px, py = i.next()
result = [(px, py)]
cur_distance = 0.0
for cx, cy in i:
cur = (cx, cy)
dx = cx - px
dy = cy - py
l = sqrt(dx * dx + dy * dy)
cur_distance += l
if cur_distance == distance:
result.append(cur)
rest = list(tuple(j) for j in i)
if len(rest) == 0:
return result, None
return result, [cur] + rest
elif cur_distance > distance:
j = l - (cur_distance - distance)
ax = dx / l * j
ay = dy / l * j
mid = (px + ax, py + ay)
result.append(mid)
return result, [mid, cur] + list(tuple(j) for j in i)
result.append(cur)
px, py = cx, cy
result.extend(tuple(j) for j in i)
return result, None
if __name__ == '__main__':
coords = [(0, 0), (1, 1)]
# cut at the beginning
assert cut(coords, 0) == (None, coords)
# cut in the middle
a, b = cut(coords, sqrt(2) / 2.0)
assert a == [(0, 0), (0.5, 0.5)]
assert b == [(0.5, 0.5), (1, 1)]
# cut at the end
a, b = cut(coords, sqrt(2))
assert a == coords
assert b == None
# cut at the end
a, b = cut(coords, 1000)
assert a == coords
assert b == None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment