Sharonica
Sharonica

Reputation: 193

finding points that reside on a line between 2 points, in accurate segments, python

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

Answers (3)

Ștefan
Ștefan

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

OMRY VOLK
OMRY VOLK

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

marcoresk
marcoresk

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

Related Questions