# Menger Sponge II

In July of 2015 I published my Menger Sponge post. As I said there, the true Menger Sponge is a three-dimensional object, but due to the lack of 3D-integration in pygame, I only showed one of the six cube’s faces. The two-dimensional fractal is officially called Siepinski carpet while the three-dimensional object is really called a Menger sponge.
To achieve the three-dimensional cube, I used Processing 3 together with its Python Mode.
The actual fractal is colored with a pseudo-randomly chosen color. All its smaller cubes then get a slight color shift. The cube rotates slowly, with a different speed on each of the three axes.

#### Controls

• Space will advance the cube’s fractalness.
• ‘q’ will save an image of the current fractal’s state.

``````# Python Code (Using Processing 3.2.1)
# Jonathan Frech 31st of August , 2016
#         edited  6th of October, 2016
#         edited  7th of October, 2016``````

``````# import
import random, os

# box class
class Box():
# init
def __init__(self, x, y, z, siz, r, g, b):
# pos
self.x = x
self.y = y
self.z = z

# size
self.siz = siz

# color
self.r, self.g, self.b = r+(random.randint(0, 1)*2-1)*10, g+(random.randint(0, 1)*2-1)*10, b+(random.randint(0, 1)*2-1)*10
self.r = max(0, min(255, self.r))
self.g = max(0, min(255, self.g))
self.b = max(0, min(255, self.b))

# render box
def render(self):
# save
pushMatrix()

# move, paint and set stroke
translate(self.x, self.y, self.z)
fill(self.r, self.g, self.b)
noStroke()

# draw actual box
box(self.siz)

# reset
popMatrix()

# generate new, smaller boxes
def gen(self):
n = self.siz/3.
b = []

# go through the 3**3 = 27 new places
for x in range(-1, 2):
for y in range(-1, 2):
for z in range(-1, 2):
# check if (x, y, z) should be kept
if (x or y) and (x or z) and (y or z):
b.append(Box(self.x+x*n, self.y+y*n, self.z+z*n, n, self.r, self.g, self.b))

return b

# handle key presses
def keyTyped():
# global variables
global boxes, tier

# generate new cube tier on space bar
if key == " ":
tier += 1
nboxes = []
for box in boxes:
# boc count could be limited
if True or len(nboxes) < 10000:
for b in box.gen():
nboxes.append(b)

boxes = nboxes

# save image
elif key == "q":
saveFrame("img.png")

# setup
def setup():
# global variables
global boxes, anglex, angley, anglez, tier

# screen size (in 3D mode)
size(720, 720, P3D)

# first box
boxes = [Box(0, 0, 0, 300, random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))]

# rotation and current tier
anglex, angley, anglez = 0, 0, 0
tier = 0

# caption
frame.setTitle("Menger Sponge")

# draw
def draw():
# global variables
global boxes, anglex, angley, anglez

# background color
background(60, 60, 130)

# save
pushMatrix()

# graphics setup
lights()
translate(width/2, height/2)
rotateX(anglex)
rotateY(angley)
rotateZ(anglez)

# draw boxes
for b in boxes:
b.render()

# reset
popMatrix()

# text
textSize(32)
translate(0, 0, 0)
fill(255, 255, 255)
text("Tier " + str(tier), 10, 30, 0)

# rotate further
anglex += .001
angley += .002
anglez += .003``````