Skip to content

Instantly share code, notes, and snippets.

@villares
Last active May 22, 2022 23:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save villares/f2072b3651a4a70d601590957fe83677 to your computer and use it in GitHub Desktop.
Save villares/f2072b3651a4a70d601590957fe83677 to your computer and use it in GitHub Desktop.
# Based on Ahmad Moussa's article https://gorillasun.de/blog/an-algorithm-for-irregular-grids#bool
# via Chris Barber https://twitter.com/code_rgb/status/1528042828219179008
# Code for Processing Python mode (py.processing.org)
from collections import namedtuple
from random import choice, sample, seed
Rect = namedtuple("Rect", "posX posY dimX dimY")
rect_infos = []
def setup():
global n_cols, n_rows, col_w, row_h, empty_spots, pad
size(800, 600)
seed(0)
# size of the padding between grid and sketch borders
pad = width / 12
# number of rows and columns of the grid
n_cols = 16
n_rows = 12
# actual spacing between grid points
col_w = (width - pad * 2) / n_cols
row_h = (height - pad * 2) / n_rows
# here we populate the 2d boolean array
empty_spots = [[True for _ in range(n_rows)] # collumn
for _ in range(n_cols)]
# add the rects!
add_to_grid([3, 1])
add_to_grid([2, 1])
add_to_grid([1, 1])
background(0)
stroke(255)
strokeWeight(4)
noFill()
draw_grid()
mark_empty()
def add_to_grid(possible_dims):
for x in range(n_cols - max(possible_dims) + 1): # I think I prefer min(possible_dims)!!!
for y in range(n_rows - max(possible_dims) + 1):
# using sample instead of choice to avoid squares, you can use choice twice...
xdim, ydim = sample(possible_dims, 2)
fits = True
# check if within bounds
if x + xdim > n_cols or y + ydim > n_rows:
continue
# check if rectangle overlaps with any other rectangle
for xc in range(x, x + xdim):
for yc in range(y, y + ydim):
if empty_spots[xc][yc] == 0:
fits = False
if fits:
# mark area as occupied
for xc in range(x , x + xdim):
for yc in range(y, y + ydim):
empty_spots[xc][yc] = False
rect_infos.append(Rect(x,y,xdim,ydim))
def draw_grid():
for r in rect_infos:
rect(r.posX * col_w + pad, r.posY * row_h + pad,
r.dimX * col_w, r.dimY * row_h)
def mark_empty():
for x in range(n_cols):
for y in range(n_rows):
if empty_spots[x][y] :
point(x * col_w + col_w/2 + pad,
y * row_h + row_h/2 + pad)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment