Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Draw line between two coordinates in a matrix

Tags:

python

I have a matrix of size N x N defined as M = np.zeros((N,N)) and two coordinates [x0,y0] and [x1,y1]. Now I want to connect these two points with ones.

An example for N=5 would be:

Lets set the coordinates to 2 in the matrix

[x0,y0] = [0,3]
[x1,y1] = [4,2]

Then the matrix should look something like:

M = 
    0 0 0 2 0
    0 0 0 1 0
    0 0 1 0 0
    0 0 1 0 0
    0 0 2 0 0

What would be a simple approach to do that?

like image 366
Gilfoyle Avatar asked May 31 '26 20:05

Gilfoyle


2 Answers

This is one simple implementation with NumPy, just computing the line equation:

import numpy as np

def draw_line(mat, x0, y0, x1, y1, inplace=False):
    if not (0 <= x0 < mat.shape[0] and 0 <= x1 < mat.shape[0] and
            0 <= y0 < mat.shape[1] and 0 <= y1 < mat.shape[1]):
        raise ValueError('Invalid coordinates.')
    if not inplace:
        mat = mat.copy()
    if (x0, y0) == (x1, y1):
        mat[x0, y0] = 2
        return mat if not inplace else None
    # Swap axes if Y slope is smaller than X slope
    transpose = abs(x1 - x0) < abs(y1 - y0)
    if transpose:
        mat = mat.T
        x0, y0, x1, y1 = y0, x0, y1, x1
    # Swap line direction to go left-to-right if necessary
    if x0 > x1:
        x0, y0, x1, y1 = x1, y1, x0, y0
    # Write line ends
    mat[x0, y0] = 2
    mat[x1, y1] = 2
    # Compute intermediate coordinates using line equation
    x = np.arange(x0 + 1, x1)
    y = np.round(((y1 - y0) / (x1 - x0)) * (x - x0) + y0).astype(x.dtype)
    # Write intermediate coordinates
    mat[x, y] = 1
    if not inplace:
        return mat if not transpose else mat.T

Some tests:

print(draw_line(np.zeros((5, 5)), 0, 3, 4, 2))
#[[0. 0. 0. 2. 0.]
# [0. 0. 0. 1. 0.]
# [0. 0. 1. 0. 0.]
# [0. 0. 1. 0. 0.]
# [0. 0. 2. 0. 0.]]
print(draw_line(np.zeros((5, 5)), 4, 2, 0, 3))
#[[0. 0. 0. 2. 0.]
# [0. 0. 0. 1. 0.]
# [0. 0. 1. 0. 0.]
# [0. 0. 1. 0. 0.]
# [0. 0. 2. 0. 0.]]
print(draw_line(np.zeros((5, 5)), 1, 0, 3, 4))
#[[0. 0. 0. 0. 0.]
# [2. 0. 0. 0. 0.]
# [0. 1. 1. 1. 0.]
# [0. 0. 0. 0. 2.]
# [0. 0. 0. 0. 0.]]
like image 119
jdehesa Avatar answered Jun 02 '26 10:06

jdehesa


If you treat the array conceptually as a matrix of pixels, then you can use Bresenhams line drawing algorithm to draw a line between these two points.

like image 45
Noufal Ibrahim Avatar answered Jun 02 '26 10:06

Noufal Ibrahim