Home > Back-end >  How to create a list of coordinates from centre coordinate in Python
How to create a list of coordinates from centre coordinate in Python

Time:11-27

I have a list with a pair of coordinates: e.g. coord_list = [[1,2]] For this coordinate, I would like to append to the list coordinates that are /- 2 points away from both the x and y coordinates. The list will contain 25 pairs of coordinates in the end, with the centre coordinate as the first element.

Any suggestions about how to go about this in Python? Thanks a lot.

CodePudding user response:

The Solution

We can construct from the x and y coordinate of the point the range of numbers of the points which are surrounding the point by up to k = 2.

Then we build all possible combinations of these possible x and y coordinate values. This can be neatly done with list expressions by combining two for-clauses. Due to your desire that the original point should be placed at the beginning, we add an if [x, y] != point clause to exclude the original point from listing by the list-expression but we add it at the beginning extra to this list-comprehension [point] [ <list-comprehension>].

The nice thing of this solution is that you can vary k, e.g. k=3 or just one layer of cells around the original cell by setting k=1.

def vary_around(val, k=2):
    return list(range(val - k, val   k   1))

def points_around(point, k=2):
    x, y = point
    xs = vary_around(x, k=k)
    ys = vary_around(y, k=k)
    return [point]   [[x, y] for x in xs for y in ys if [x, y] != point]

Test It

You can try it:

In [39]: points_around([1, 2], k=2)
Out[39]: 
[[1, 2],
 [-1, 0],
 [-1, 1],
 [-1, 2],
 [-1, 3],
 [-1, 4],
 [0, 0],
 [0, 1],
 [0, 2],
 [0, 3],
 [0, 4],
 [1, 0],
 [1, 1],
 [1, 3],
 [1, 4],
 [2, 0],
 [2, 1],
 [2, 2],
 [2, 3],
 [2, 4],
 [3, 0],
 [3, 1],def points_around(point, k=2):
    x, y = point
    xs = vary_around(x, k=k)
    ys = vary_around(y, k=k)
    return {tuple(point): [[x, y] for x in xs for y in ys if [x, y] != point]}

# now, you get:
reduce(lambda dct, dct1: dct.update(dct1) and dct, [points_around(point, k=2) for point in coord_list])


 [3, 2],
 [3, 3],
 [3, 4]]

In [40]: len(points_around([1, 2], k=2))
Out[40]: 25

With:

coord_list = [[1, 2], [3, 4]]

You apply this function again using list-comprehensions:

point_groups = [points_around(point, k=2) for point in coord_list]

Further Suggestion

Probably you want the original point at the beginning to have it distinguished from the rest of the points.

How about using a dictionary for this purpose?


def merge_dicts(dct, dct1):
    dct.update(dct1)
    return dct

def points_around(point, k=2):
    x, y = point
    xs = vary_around(x, k=k)
    ys = vary_around(y, k=k)
    return {tuple(point): tuple([(x, y) for x in xs for y in ys if [x, y] != point])} # key must be a tuple and not a list
# in a dictionary so probably better to make everything a tuple

from functools import reduce

defun coords_to_points_dict(coord_list, k=2):
    return reduce(merge_dicts, [points_around(point, k=k) for point in coord_list])

point2surrounding_points = coords_to_points_dict(coord_list, k=2)

point2surrounding_points
# it outputs:

{(1, 2): ((-1, 0),
  (-1, 1),
  (-1, 2),
  (-1, 3),
  (-1, 4),
  (0, 0),
  (0, 1),
  (0, 2),
  (0, 3),
  (0, 4),
  (1, 0),
  (1, 1),
  (1, 3),
  (1, 4),
  (2, 0),
  (2, 1),
  (2, 2),
  (2, 3),
  (2, 4),
  (3, 0),
  (3, 1),
  (3, 2),
  (3, 3),
  (3, 4)),
 (3, 4): ((1, 2),
  (1, 3),
  (1, 4),
  (1, 5),
  (1, 6),
  (2, 2),
  (2, 3),
  (2, 4),
  (2, 5),
  (2, 6),
  (3, 2),
  (3, 3),
  (3, 5),
  (3, 6),
  (4, 2),
  (4, 3),
  (4, 4),
  (4, 5),
  (4, 6),
  (5, 2),
  (5, 3),
  (5, 4),
  (5, 5),
  (5, 6))}

This dictionary you can query with your points to get their surrounding points.

CodePudding user response:

You could use a list comprehension to generate the 24 additional coordinates and append them to the original list:

coords  = [[1,2]]
coords  = [ [x d//5-2,y d%5-2] for x,y in coords
            for d in range(25) if d != 12 ]

print(coords)
[[1, 2],  [-1, 0], [-1, 1], [-1, 2], [-1, 3], 
 [-1, 4], [0, 0],  [0, 1],  [0, 2],  [0, 3], 
 [0, 4],  [1, 0],  [1, 1],  [1, 3],  [1, 4], 
 [2, 0],  [2, 1],  [2, 2],  [2, 3],  [2, 4], 
 [3, 0],  [3, 1],  [3, 2],  [3, 3],  [3, 4]]

You could generalize it into a function for any distance like this:

def addNeighbors(coords,distance=2):
    coords  = [ [x dx,y dy] for x,y in coords
                for dx in range(-distance,distance 1)
                for dy in range(-distance,distance 1)
                if dx or dy ]
  • Related