Search code examples
pythonpython-3.xpolygonshapely

How to make sure generated random boundingboxes within another boundingbox are not overlapping?


I have a boundingbox

a = [233.9259,  16.3902, 356.8651, 426.9131]

import shapely.geometry
bbox = (233.9259,  16.3902, 356.8651, 426.9131)
polygon = shapely.geometry.box(*bbox, ccw=True)
polygon.bounds  # (233.9259, 16.3902, 356.8651, 426.913

and I randomly generated 10 random boundingboxes with the size 8x8

import random
from shapely.geometry import Polygon, Point

min_x, min_y, max_x, max_y = polygon.bounds
width = 8# to be defined
height = 8# to be defined
num_polygons = 10# to be defined
random_poly = []

while len(random_poly) < num_polygons:
  rand_x = random.uniform(min_x, max_x)
  rand_y = random.uniform(min_y, max_y)

  left = Point([rand_x, rand_y])
  bottom = Point([rand_x, rand_y - height])
  right = Point([rand_x + width, rand_y - height])
  top = Point([rand_x + width, rand_y])

  new_poly = Polygon([left, bottom, right, top])

  if polygon.contains(new_poly):
    random_poly.append(new_poly) 

enter image description here

How to make sure these generated bounding boxes are non-overlapping?


Solution

  • Extending the code provided with one additional conditional will do the trick.

    This may not be most performant way to do it, but seeing the example code that doesn't seem to be the objective.

    import random
    
    from matplotlib import pyplot as plt
    from shapely.geometry import Polygon, Point
    import shapely
    
    bbox = (233.9259, 16.3902, 356.8651, 426.9131)
    bounding_box = shapely.geometry.box(*bbox)
    
    min_x, min_y, max_x, max_y = bounding_box.bounds
    width = 8  # to be defined
    height = 8  # to be defined
    num_polygons = 10  # to be defined
    random_polygons = []
    
    while len(random_polygons) < num_polygons:
        rand_x = random.uniform(min_x, max_x)
        rand_y = random.uniform(min_y, max_y)
    
        left = Point([rand_x, rand_y])
        bottom = Point([rand_x, rand_y - height])
        right = Point([rand_x + width, rand_y - height])
        top = Point([rand_x + width, rand_y])
    
        new_poly = Polygon([left, bottom, right, top])
    
        if bounding_box.contains(new_poly) and not shapely.MultiPolygon(random_polygons).touches(new_poly):
            random_polygons.append(new_poly)