Reputation: 189
Given a set of points and a line in 2D, I would like to plot the orthogonal distance between each point and the line. Any suggestions?
Upvotes: 1
Views: 1402
Reputation: 1744
This is more like a math question.
What @jacob says is perfect solution using coordinate geometry. If you prefer to use vector math (and hence numpy
arrays as vectors), you can go about it like this:
Consider the vector equation of a line: L = A + ql
(q is a free parameter, the one we wish to find)
The position vector of your point: P
The orthogonality condition (just the dot product being zero): L . P = 0
Hence, (A + ql) . P = 0
or, q = - (A . P / l . P)
(Bold denotes a vector, bold-small denotes a unit vector, all else are scalars)
We've found q; substituting q in the vector equation of the line yields the position vector of the point which intersects with the perpendicular from the point dropped on the line. Now just find the distance between the two points, which is the magnitude of the difference vector:
d = |P - L(q)|
A numpy
implementation is pretty straightforward:
(Define A, l and P as numpy arrays first)
...
L = A + lambda q: q*l // define the line as a function of q
q = - numpy.dot(A, P)/numpy.dot(l, P) // find q subject to condition
d = numpy.linalg.norm(P - L(q)) // find the norm of the difference vector
The advantage to this method is, it works in N-dimensions as well.
Here is a resource to refer to, on vector equations of lines.
Upvotes: 2
Reputation: 1097
Find the equation of your given line in the form of y = m*x + b
where m
is slope and b
is your y-intercept. The slope of the perpendicular line is the negative inverse of your known slope (i.e. m2 = -1/m
). Use the given point and the new slope m2
to get the equation of the line perpendicular to the given line which goes through your point. Set the second line equal to the first and solve for x
and y
. This is where the two lines intersect. Get the difference between the intersection and find the magnitude to determine distance between the given line and the given point:
distance = ((x2 - x)**2 + (y2 - y)**2)**0.5
where [x2, y2]
is the given point and [x, y]
is the intersection.
More precisely, the following image was generated to illustrate this technique with sample code below:
import matplotlib.pyplot as plt
import numpy as np
# points follow [x, y] format
line_point1 = [2, 3]
line_point2 = [6, 8]
random_point = [-6, 5]
def line(x, get_eq=False):
m = (line_point1[1] - line_point2[1])/(line_point1[0] - line_point2[0])
b = line_point1[1] - m*line_point1[0]
if get_eq:
return m, b
else:
return m*x + b
def perpendicular_line(x, get_eq=False):
m, b = line(0, True)
m2 = -1/m
b2 = random_point[1] - m2*random_point[0]
if get_eq:
return m2, b2
else:
return m2*x + b2
def get_intersection():
m, b = line(0, True)
m2, b2 = perpendicular_line(0, True)
x = (b2 - b) / (m - m2)
y = line(x)
return [x, y]
domain = np.linspace(-10, 10)
plt.figure(figsize=(8, 9))
plt.plot(domain, [line(x) for x in domain], label='given line')
plt.plot(random_point[0], random_point[1], 'ro', label='given point')
plt.plot(domain, [perpendicular_line(x) for x in domain], '--', color='orange', label='perpendicular line')
intersection = get_intersection()
plt.plot(intersection[0], intersection[1], 'go', label='intersection')
plt.plot([intersection[0], random_point[0]], [intersection[1], random_point[1]], color='black', label='distance')
plt.legend()
plt.grid()
plt.show()
distance = ((random_point[0] - intersection[0])**2 + (random_point[1] -
intersection[1])**2)**0.5
print(distance)
Upvotes: 3