1

I wrote a basic code which accepts two point coordinates, derives the eqaution of the line passing through it and of the perpendicular, then outputs two points which are the edges of the same perpendicular line. My aim is to do something like what is shown in the pictures of this answer, but without all those third-party packages, and without a GIS.

Now, talking about performance, I think my code could greatly benefit of the numpy package, especially in view of using this calculations in a loop with lots (even millions) of pair of point coordinates. Since I didn't use numpy so much, can anyone:

  1. (confirm that adapting the code to use numpy would enhance the performance)
  2. suggest of should I adapt the code (e.g. some good hint to start)?

Here is the code, hope someone would find it useful (matplotlib is there just to visualize the result).

import matplotlib.pyplot as plt

# calculate y from X coord, slope and intercept
def calculate_y(x, m, q):
    y = m * x + q
    return y

# the two point coordinates
point_A = [5,7] # First considered point
point_B = [4,10] # Second considered point

# calculate the slope between the point pair
m = (point_A[1] - point_B[1]) / (point_A[0] - point_B[0])

# calculate slope and intercept of the perpendicular (using the second original point)
m_perp = -(1/m)
q_perp = point_B[1] - m_perp * point_B[0]
##print "Perpendicular Line is y = {m}x + {q}".format(m=m_perp,q=q_perp)

# calculate corods of the perpendicular line
distance_factor = 1 #distance from central point
min_X = point_B[0] - distance_factor # left-side X
min_Y = calculate_y(min_X, m_perp, q_perp) # left-side Y

max_X = point_B[0] + distance_factor # right-side X
max_Y = calculate_y(max_X, m_perp, q_perp) # right-side Y

perp_A = (min_X, min_Y)
perp_B = (max_X, max_Y)

x_coord, y_coord = zip(*[point_A, point_B])
x_perp_coord, y_perp_coord = zip(*[perp_A, perp_B])

plt.scatter(x_coord, y_coord)
plt.scatter(x_perp_coord, y_perp_coord)
plt.show()
2
  • 1
    Maybe we can get rid of the loops themselves for noticeable speedup. So, it might be beneficial to see how you are using the loops with the input data. Commented Oct 3, 2016 at 14:48
  • I would read one by one each pair of coordinates from a txt file. Each pair of coordinate is a point on a line and the following one, at a fixed distance (progressive points on a line). So I would make a list of all the XY coordinates (sorted) and in the loop I would process each pair separately (e.g. the first and second point (first pair), then the second and third (second pair), and so on). Commented Oct 3, 2016 at 14:54

1 Answer 1

1

1) Yes, numpy would increase the performance a lot. Instead of doing a loop in python, you have it in C using the vectorization of numpy.

2) ideas:

import matplotlib.pyplot as plt
import numpy as np

# get random coords
npts = 10
distance_factor = 0.05
points = (np.sort(np.random.random(2*npts)).reshape((npts,2)) \
         + np.random.random((npts,2))/npts).T
points_x = points[0]  # vector of the chain of x coords
points_y = points[1]  # vector of the chain of y coords
plt.plot(points_x, points_y, 'k-o')
plt.gca().set_aspect('equal')
points_x_center = (points_x[1:] + points_x[:-1])*0.5
points_y_center = (points_y[1:] + points_y[:-1])*0.5
plt.plot(points_x_center, points_y_center, 'bo')
ang = np.arctan2(np.diff(points_y), np.diff(points_x)) + np.pi*0.5
min_X = points_x_center + distance_factor*np.cos(ang)
min_Y = points_y_center + distance_factor*np.sin(ang)
max_X = points_x_center - distance_factor*np.cos(ang)
max_Y = points_y_center - distance_factor*np.sin(ang)
plt.plot(np.vstack((min_X,max_X)), np.vstack((min_Y,max_Y)), 'r-')
plt.plot(np.vstack((min_X,max_X)).T, np.vstack((min_Y,max_Y)).T, 'r-', lw=2)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.