Visualizing cellular automata
In this post I plan to set the scene for a nice visualization of cellular automata and pretty much anything else.
The idea is basically a mix of Github ability to preview .stl
3d files and the illustration in Wolfram’s “A new kind of science”.
Bulding on what I did in the previos post, once the run for a CA rule has been generate, it’s easy to manipulare the bits and generate vertexes and faces of the 3d figure (in this case the format is .obj)
import numpy as np
import math
import matplotlib.pyplot as plt
import import_ipynb
from automata_generation import generate, plot_run, make_columns
# manually specify the logic to map a cube face to 4 of its 8 vertexes
def face(face, count):
if face == 1:
return f'f {count+1} {count+2} {count+4} {count+3}'
elif face == 2:
return f'f {count+1} {count+2} {count+6} {count+5}'
elif face == 3:
return f'f {count+2} {count+6} {count+8} {count+4}'
elif face == 4:
return f'f {count+3} {count+4} {count+8} {count+7}'
elif face == 5:
return f'f {count+1} {count+5} {count+7} {count+3}'
elif face == 6:
return f'f {count+5} {count+6} {count+8} {count+7}'
def generate_cell(file, count, i, j):
start = count * 8
lines = [f'g cell{i}-{j}\n', 'usemtl Red\n']
vertex = []
z = 0
for di in [0, 1]:
for dj in [0, 1]:
for dz in [0, 1]:
vertex.append(f'v {j+dj} {i+di} {z+dz}\n')
for v in vertex:
lines.append(v)
for i in range(6):
lines.append(face(i+1, start) + '\n')
lines.append("\n")
file.writelines(lines)
def create_3d_obj(rule, data):
count = 0
filename = f'{rule}.obj'
file = open(filename, "w")
file.writelines(["mtllib automata.mtl\n"])
for i, row in enumerate(data):
for j, col in enumerate(row):
if data[i][j] == 1: # 0 or 1 depending on the CA
generate_cell(file, count, len(data)-i, j)
count += 1
file.close()
return filename
rule = 30
size = 200
steps = 200
start = np.zeros(size)
start[45:55] = 1
data, _ = generate(rule, size, steps, with_init=start)
create_3d_obj(rule, data)
'30.obj'
And here’s the result
This gets even more cool with 2D CA
Coming soon:
I’m no expert on 3d visualization but I think the reason the figures are a bit laggy, especially if they are large enough, is that each CA cell is its own figure. One optimization that I’ll try to implement in the future is to merge all adjacent cells into one figure (this mean that all non-edge vertex can be removed and several faces merged together).
I’ll probably need to use use SCC to undersand which cells should be merged together. The tricky thing will probably be specifying the vertexes for such non regular faces (since the list of vertex needs to be ordered - in general counter clock wise). I will probably need to used some idea from the convex hull to specify such ordering.
It should be fun
Enjoy Reading This Article?
Here are some more articles you might like to read next: