A small extension to the original code.
The above Version (with the rectangle size of cell size / sqrt(2)) is only one of a series of four. Depending on the size of the rectangles they touch in different ways.
So here is the updated code to use the same rotation pattern on four pages with different rectangle sizes.
First let’s store the size of the canvas (1000) in the variable canvas_s.
The amount variable and calculation of the cell size stays the same:
canvas_s = 1000
amount = 24
cell_s = canvas_s / (amount + 2)
The four different rectangle sizes are stored in a list.
rect_sizes = [ cell_s / 2, cell_s / sqrt(2), 2 * cell_s / ( 1 + sqrt(2) ), cell_s]
The sizes are calculated to get the various ‘touchings’. Just add other rectangle sizes to the list and see that you get.
cell_s / 2: no touching
cell_s / sqrt(2): the rotated rectangles tough on the corners
2 * cell_s / (1 + sqrt(2)): a rotated and default rectangle touch on the corner and side
cell_s: the not rotated rectangles touch on the side
To use the same rotation grid we have to generate and store it somehow.
Let’s use the nested loops to store this information in the grid variable.
It is a list of lists (rows or columns whatever you prefere).
Declare the variable and store an empty list:
grid = []
Loop though the amount
for y in range(amount):
For every row we assign a new empty list to the newRow variable
newRow = []
Then loop through the amount and append either True or False to the newRow
for x in range(amount):
if random() > .5:
newRow.append(True)
else:
newRow.append(False)
When we are finished with the row loop let’s append the newRow to the grid
grid.append( newRow )
The above grid generation could actually be done in one line as well.
So this:
grid = []
for y in range(amount):
newRow = []
for x in range(amount):
if random() > .5:
newRow.append(True)
else:
newRow.append(False)
grid.append( newRow )
Will do the same as this:
grid = [[True if random() > .5 else False for x in range(amount)] for y in range(amount)]
List comprehension and ternary operators are great and will save you some lines but they can be a bit confusing.
The rest of the script basically stays the same.
There is one more loop added to generate the pattern for each size:
for rect_s in rect_sizes:
For each size we need a new canvas so we call newPage() and use the variable canvas_s to make them all the same size:
newPage(canvas_s, canvas_s)
Translation for the margin
translate( cell_s, cell_s)
To loop through the stored grid let’s use the enumerate() function.
This is very helpful if you need the index and the actual element of a list.
for index, value in enumerate(['a', 'b', 'c']):
print index, value
will print (in python 2.7)
0 a
1 b
2 c
We will use the index for the transformation and the element (True or False) for the rotation.
for r, row in enumerate(grid):
for c, cell in enumerate(row):
with savedState():
translate( c * cell_s + cell_s/2, r * cell_s + cell_s/2 )
if cell: rotate(45)
rect(-rect_s/2, -rect_s/2, rect_s, rect_s)
If you want to store seperate images (.jpg or .png) we call the saveImage() inside the size loop.
saveImage('~/Desktop/Vera_Molnar_rotating_rects_%f.png' % rect_s)
For a multipage pdf or gif the saveImage() should be outside of the loops.
The full code
canvas_s = 1000
amount = 24
cell_s = canvas_s / (amount + 2)
rect_sizes = [ cell_s / 2, cell_s / sqrt(2), 2 * cell_s / ( 1 + sqrt(2) ), cell_s]
grid = [[True if random() > .5 else False for x in range(amount)] for y in range(amount)]
for rect_s in rect_sizes:
newPage(canvas_s, canvas_s)
translate( cell_s, cell_s)
for r, row in enumerate(grid):
for c, cell in enumerate(row):
with savedState():
translate( c * cell_s + cell_s/2, r * cell_s + cell_s/2 )
if cell: rotate(45)
rect(-rect_s/2, -rect_s/2, rect_s, rect_s)
# saveImage('~/Desktop/Vera_Molnar_rotating_rects_f.png' % rect_s)
You should get something like this