Reputation: 193
I have 2 points, (x0,y0) (x1,y1) which form a line L. I found the slope M. Now I want to find 3 points between these 2 points that reside on L, that is between them in an accurate distance, meaning same distance between all points. If I measure the distance with the "-" char, it can be something like: p1---p2---p3---p4---p5 where p1 and p5 are my starting points.
First I thought about finding the slope by doing something like this:
def findSlope(p1, p2):
if (p1[0] - p2[0] != 0):
return (p1[1] - p2[1])/p1[0] - p2[0]
else:
return 0
This is pretty easy, but getting the actual points is not coming easy to me. I thought about doing something like this:
def findThreePoints(p1,p2):
slope = findSlope(p1,p2)
c = p1[1] - slope*p1[0]
x1 = (p1[0] + p2[0])/4
x2 = (p1[0] + p2[0])/2
x3 = (3*(p1[0] + p2[0]))/4
y1 = slope*x1 + c
y2 = slope*x2 + c
y3 = slope*x3 + c
While this approach works, it is not very nice coding style/efficiency, since if I want the function to give more than 3 points, I will need it to be much longer.
Is there any built in way to do this with Numpy, or just a more efficient approach to the matter, that does not make my code look like it was written for only a certain purpose?
Upvotes: 1
Views: 3549
Reputation: 800
Here is a general numpy
one liner following the same interface as the line_nd
method from skimage
, but that works for any n dimensional points, not only for 2D:
import numpy as np
line_nd_np = lambda start, stop, num_points: tuple([np.linspace(start[i], stop[i], num=num_points) for i in range(len(start))])
line_nd_np(start=(0,0,0), stop=(1,1,1), num_points=3)
So, following the same interface as line_nd
, line_nd_np
returns a tuple with numpy arrays of each coordinate one by one (e.g. (xs, ys, zs,...)).
(array([0. , 0.5, 1. ]), array([0. , 0.5, 1. ]), array([0. , 0.5, 1. ]))
If one wants only an array with points on the line between start and end, the one liner can become:
import numpy as np
line_points = lambda start, stop, num_points=100: np.vstack([np.linspace(start[i], stop[i], num=num_points) for i in range(len(start))]).T
line_points(start=(0,0,0), end=(1,1,1), num_points=3)
Then, one can get:
array([[0. , 0. , 0. ],
[0.5, 0.5, 0.5],
[1. , 1. , 1. ]])
Upvotes: 0
Reputation: 1481
As simple as it gets:
import numpy as np
#create the points
number_of_points=3
xs=np.linspace(x0,x1,number_of_points+2)
ys=np.linspace(y0,y1,number_of_points+2)
#print them
for i in range(len(xs)):
print (xs[i],ys[i])
And it also works for horizontal or vertical lines
Upvotes: 7
Reputation: 1965
If equation of a line is
y = m*x + q
why not use a FOR loop? Something like:
import numpy
#define n in the code or by input
n = 100
#define the x and y arrays with numpy.array
x = numpy.zeros(n)
y = numpy.zeros(n)
#define the start, stop values in your code or by input
start = 1
stop = 10
#define the step, depending by n
step = (stop - start)/n #if you want n points
i = 0
for a in numpy.arange (start, stop, step):
x[i] = a
y[i] = m*a + q
i = i + 1 #there are better ways to do this
Of course this does not work for vertical lines, but there is no problem in finding points for these lines (x is constant)
Upvotes: 1