Search code examples
python-3.xgeometryshapely

Calculates the number of rows and columns based on the bounds of the Shapely polygon and given radius and distance


I want to find the number of rows and columns possible inside a shapely polygon. The purpose is I need to create circles inside each cell. Also there will be a value for radius and distance between these circles.

import numpy as np
from shapely.geometry import Polygon

def generate_circles(pointsdata, radius, distance):
    
    points_data = np.array(pointsdata['DataPoints']).astype(float)
    x_coords, y_coords = points_data[:, 0], points_data[:, 1]
    shapely_polygon = Polygon(list(zip(x_coords, y_coords)))
    if shapely_polygon.is_empty or not shapely_polygon.exterior:
            pass
    else : 
           #I want to find number of rows and columns possible 
           #inside this polygon considering the radius and distance


pointsdata = { 'NumberofDataPoints': 8, "DataPoints": [ [0, 0], [1, 0.5], [1.5, 1.5], [1, 2.5], [0, 3], [-1, 2.5], [-1.5, 1.5], [-1, 0.5] ] } 
radius = 1.5
distance = 2
generate_circles(pointsdata,radius,distance)

How can i find number of rows and columns possible?


Solution

  • IIUC, you're trying to do some sort of Circle Packing.

    If so, you can try the option below (inspired by set_grid from @Pierrick Rambaud) :

    import numpy as np
    from itertools import product
    from shapely import Point, Polygon
    
    def generate_circles(pointsdata, radius, distance):
        poly = Polygon(pointsdata["DataPoints"])
        min_x, min_y, max_x, max_y = poly.bounds
    
        x = np.concatenate([np.arange(min_x, max_x, distance), [max_x]])
        y = np.concatenate([np.arange(min_y, max_y, distance), [max_y]])
    
        circles = []
        for ix, iy in product(range(len(x) - 1), range(len(y) - 1)):
            if (circ := Point((x[ix + 1], y[iy + 1])).buffer(radius)).within(poly):
                circles.append(circ)
    
        return poly, circles
    
    poly, circles = generate_circles(pointsdata, 0.1, 0.2)
    

    enter image description here