Karak
Karak

Reputation: 129

How to calculate the coordinates of the line between two points in python?

How can I get all the coordinate points between two points in python? For example: I have a point with the coordinates of x1, y1 and an other with x10, y10. I need all the points between them (in this case for instance x2, y2 ... x9, y9). Huge thanks for your help!

Upvotes: 9

Views: 29037

Answers (4)

MBV
MBV

Reputation: 640

Elaborating on the answer provided by Thierry Lathuille, you could try to make a vectorized version as the code below. This code was written to insert extra points in a wkt geometry that is why it has the z_v points, with two options, either insert a fix quantity of points (n_p) between existing coordinates points or insert points at a given fixed distance (d) from each other between existing coordinates points .

Also, "BORRAR - REVISION GRAFICA DE LOS PUNTOS" it is just a way to see the code is working properly in a visual way, comment this out once you are sure your point placement works.

v range function was found here in stackoverflow but cannot seem to find the post to refer, I just modified it a bit.

EDIT: Using Python 3.9, now on the same WKT geometry my machine gets a ~34X time reduction.

 def vrange(stops):
    """Create concatenated ranges of integers for multiple [1]/stop

    Parameters:
        starts (1-D array_like): starts for each range
        stops (1-D array_like): stops for each range (same shape as starts)

    Returns:
        numpy.ndarray: concatenated ranges
    """
    starts = np.array([1] * len(stops))
    stops = np.asarray(stops) + 1
    L_p = stops - starts
    return np.array(np.split(np.repeat(stops - L_p.cumsum(), L_p) + np.arange(L_p.sum()), np.cumsum(stops - 1)[:-1]))

def get_points_v(x_v, y_v, z_v, d=None, n_p= None):
        "DESEMPACAR ARRAY DE WKT"
        x_v, y_v, z_v = np.asarray(x_v), np.asarray(y_v), np.asarray(z_v)

        "DISTANCIAS ENTRE X(n) - X(n-1), Y(n) - Y(n-1)"
        Lx, Ly = np.array(x_v[1:] - x_v[:-1]), np.array(y_v[1:] - y_v[:-1])

        "EXCLUIR LINEAS DE LONGITUD MENOR A LA DISTANCIA 'd'"
        if d and np.sum(np.asarray(((x_v[1:] - x_v[:-1]) ** 2 + (y_v[1:] - y_v[:-1]) ** 2) ** 0.5)) < d:
            print(np.sum(Lx), np.sum(Ly))
            pass
        else:
            "NUMERO DE PUNTOS ENTRE VERTICES"
            if n_p is None:
                nx, ny = np.array(np.around(np.abs(Lx / d), decimals=0)), np.array(np.around(np.abs(Ly / d), decimals=0))
                nx, ny = np.where(nx <= 0, 1, nx).astype(np.int), np.where(ny <= 0, 1, ny).astype(np.int)
                n_points = np.maximum(nx, ny)
            else:
                n_points = np.array([1] * len(Lx)) * np.array(n_p)

            "LONGUITUD DE SEGMENTOS ENTRE PUNTOS"
            x_space, y_space = Lx / (n_points + 1), Ly / (n_points + 1)

            "CREAR 2D ARRAY DE VALORES INICIALES"
            x_init, y_init = np.array(np.split(np.repeat(x_v[:-1], n_points), np.cumsum(n_points)[:-1])), np.array(np.split(np.repeat(y_v[:-1], n_points), np.cumsum(n_points)[:-1]))

            "CREAR RANGO DE NUMERO DE SEGMENTOS (n_points)"
            range_n = vrange(n_points)

            "CALCULO DE PUNTOS INTERMEDIOS ENTRE SEGMENTOS DE X_V y Y_v"
            if n_p is None:
                points_x, points_y = x_init + (range_n * x_space).T, y_init + (range_n * y_space).T
            else:
                points_x, points_y = x_init + (range_n * x_space[:, None]), y_init + (range_n * y_space[:,None])

            "GENERAR ARRAY DE VALORES z_v"
            points_z = np.split(np.repeat(np.array([z_v[0]] * len(points_x)), n_points), np.cumsum(n_points)[:-1])

            "BORRAR - REVISION GRAFICA DE LOS PUNTOS"
            import matplotlib.pyplot as plt
            [plt.plot(m, n, marker='o', color='red') for m,n in zip(points_x, points_y)]
            plt.plot(line.T[0], line.T[1], linewidth=1, color='C0',marker='>')
            plt.show()
            return points_x, points_y, points_z

Figure n_p=3 Figure n_p=3

Figure d= 0.5m Figure d= 0.25m

Upvotes: 0

duffymo
duffymo

Reputation: 309008

"All of them"? There are an infinite number.

You can calculate the slope and intercept of the line between those two points. Knowing those you can calculate the value for y at every value of x you wish using the equation for the line.

This is high school algebra. What's the problem?

Given two points (x1, y1) and (x2, y2) the equation for the line between them is:

y = m*x + b

where

m = slope = (y1-y2)/(x1-x2)

and

b = y-intercept = (x1*y2 - x2*y1)/(x1-x2)

If you mean "draw the circle passing between the two points and find all the points inside", I'd calculate the center point as the midpoint of that line and radius equal to half the length of that line. You calculate whether or not a point is inside or outside the circle by determining the distance from the center and comparing it to the radius.

There are an infinite numbers of points both inside and outside the circle. What are you really trying to do here?

Upvotes: 14

MBo
MBo

Reputation: 80325

Seems you want to generate a list of integer points for the line segment between given points. This problem is solved in computer graphics, for example, using Bresenham algorithm or DDA algo

Upvotes: 8

Thierry Lathuille
Thierry Lathuille

Reputation: 24291

def intermediates(p1, p2, nb_points=8):
    """"Return a list of nb_points equally spaced points
    between p1 and p2"""
    # If we have 8 intermediate points, we have 8+1=9 spaces
    # between p1 and p2
    x_spacing = (p2[0] - p1[0]) / (nb_points + 1)
    y_spacing = (p2[1] - p1[1]) / (nb_points + 1)

    return [[p1[0] + i * x_spacing, p1[1] +  i * y_spacing] 
            for i in range(1, nb_points+1)]

print(intermediates([1, 2], [10, 6.5], nb_points=8))

# [[2.0, 2.5], [3.0, 3.0], [4.0, 3.5], [5.0, 4.0], 
#  [6.0, 4.5], [7.0, 5.0], [8.0, 5.5], [9.0, 6.0]]

Upvotes: 9

Related Questions