Repository navigation
Expand file tree
/
Copy pathvector.py
More file actions
80 lines (61 loc) · 1.86 KB
/
Copy pathvector.py
File metadata and controls
80 lines (61 loc) · 1.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import math
# http://www.fundza.com/vectors/point2line/index.html
def dot(v, w):
x, y = v
X, Y = w
return x * X + y * Y
def length(v):
x, y = v
return math.sqrt(x * x + y * y)
def vector(b, e):
x, y = b
X, Y = e
return (X - x, Y - y)
def unit(v):
x, y = v
mag = length(v)
return (x / mag, y / mag)
def distance(p0, p1):
return length(vector(p0, p1))
def scale(v, sc):
x, y = v
return (x * sc, y * sc)
def add(v, w):
x, y = v
X, Y = w
return (x + X, y + Y)
# Given a line with coordinates 'start' and 'end' and the
# coordinates of a point 'pnt' the proc returns the shortest
# distance from pnt to the line and the coordinates of the
# nearest point on the line.
#
# 1 Convert the line segment to a vector ('line_vec').
# 2 Create a vector connecting start to pnt ('pnt_vec').
# 3 Find the length of the line vector ('line_len').
# 4 Convert line_vec to a unit vector ('line_unitvec').
# 5 Scale pnt_vec by line_len ('pnt_vec_scaled').
# 6 Get the dot product of line_unitvec and pnt_vec_scaled ('t').
# 7 Ensure t is in the range 0 to 1.
# 8 Use t to get the nearest location on the line to the end
# of vector pnt_vec_scaled ('nearest').
# 9 Calculate the distance from nearest to pnt_vec_scaled.
# 10 Translate nearest back to the start/end line.
# Malcolm Kesson 16 Dec 2012
def pnt2line(pnt, start, end):
line_vec = vector(start, end)
pnt_vec = vector(start, pnt)
line_len = length(line_vec)
line_unitvec = unit(line_vec)
pnt_vec_scaled = scale(pnt_vec, 1.0 / line_len)
t = dot(line_unitvec, pnt_vec_scaled)
r = 1
if t < 0.0:
t = 0.0
r = -1
elif t > 1.0:
t = 1.0
r = -1
nearest = scale(line_vec, t)
dist = distance(nearest, pnt_vec)
nearest = add(nearest, start)
return (dist, (int(nearest[0]), int(nearest[1])), r)