Printing Fractals on MiniFactory

Last week, we had our 8th International IT Week for Students here at HAAGA-HELIA where I work. We had teams from Spain, Denmark, and Finland, and we looked into issues like mobile games development, robot building on the Arduino set, and on the Danish day, fractals. My good friend and colleague from Coopenhagen North, Anders Kalhauge, presented a lecture, and the students then led a workshop into fractals.

Fractals are odd creatures. Wikipedia says that

“A fractal is a mathematical set that typically displays self-similar patterns, which means it is “the same from near as from far”. Fractals may be exactly the same at every scale, or, […] they may be nearly the same at different scales. The concept of fractal extends beyond self-similarity and includes the idea of a detailed pattern repeating itself.”

To show you a fractal, I will grab a copy of one from Wikimedia Commons. This is the Mandelbrot set, the most famous of fractals.

Mandelbrot set

Mandelbrot set, the most famous of all fractals

During his lecture, Anders showed us how a simple recursive formula will eventually yield this image, and how you can edit the parameters in the formula to change the resulting image. This is fascinating stuff, even if the mathematics are beyond many people, and most definitely beyond my feeble grasp of math. But anyhow, Anders got to thinking about Blender.

Since Blender is built on the Python language, and Anders knows Python well, he wanted to see if he could run the Mandelbrot math and come up with a Blender mesh, ie. a solid virtual object, where the colors of the fractal would be represented with different elevations. The red outer area would be the zero elevation, and it would build up gradually to the black plateau in the middle. If that were possible, he thought, maybe we could then export the mesh from Blender and print a solid object. He worked on this idea overnight and got it working, and on the next day, he presented me with this Blender file:

blender running mandelbrot

Anders’ script and the mesh

I was amazed. This little script on the right creates this mesh you see on the left, and you can edit the parameters to come up with a different fractal form if you wish. The current one runs on a twodimensional array of 1000 x 1000 vertices, ie. one million points. But when Anders showed me this, I knew it could be turned into a printable piece. We did some experimenting, and after fifteen minutes, we had the print-ready STL file.

Now, most of the time, meshes need to be manifold to print. Manifold means there are no loose edges, no holes, and no vertices that are unattached. The Blender 3D Print Tools add-on reported that there were about 400 loose edges, which usually would be a showstopper for printing. However, this time, the resolution of the printer is not even close to the resolution of the mesh. Therefore the extrusion of material would fill in any of these gaps anyway, and even if the Slic3r program alerted us to such problems, we forged ahead.

The STL file looked okay when I placed it on the table and scaled it by 25. I could have scaled it in Blender just as well, but I decided to do it here and see how it sat on the table.

mandelbrot on printer table

The STL file imported to Repetier Host and scaled

A moment later Slic3r finished, and we had the G-code that would turn the virtual object into a very real one fith 53,000 moves of the table and the printer nozzle. I hit Print.

Mandelbrot set on table

Finished print of Mandelbrot set

So, after 25 minutes, we could see the finished object on the table. Given its small scale, and the infill set at 60%, the job finished very fast, but the outcome was better than I had hoped for. It shows all the classic features of the Mandelbrot set, just as it should, since it was created using the very formula. When you hold this against the window, you can see how its inner forms conform to the image on the top even better:

Printed fractal on window

Printed fractal on window

So, our little test turned out to work straight off the box. My hat’s off to Anders, whose knowledge of math and fractals, and Python of course, enabled him to pull this off at one go. For those who are interested in the code, it is inside this Blender file, and if you just press the Run Script button, you can see it create another mesh in seconds (delete the previous one before you do).

Get the Blender file here.

And this is the code:

import bpy
import math
vr, vi = 200, 200
limit, iterations, max_height = 10000000.0, 1024, 0.25
p = -2.25 - 1.5j
d = 3.0 + 3.0j
def index(x, y):
 return y*(vr + 1) + x
def mandelpoint(c):
 z = c
 for h in range(iterations):
 if z.real*z.real + z.imag*z.imag > limit: break
 z = z*z + c
 return (c.real, c.imag, max_height*math.log(h)/math.log(iterations))
vertices = [ mandelpoint(x*d.real/vr + (y*d.imag/vi)*1j + p) 
for y in range(vi + 1) for x in range(vr + 1) ]
faces = [
 (index(x, y), index(x + 1, y), index(x + 1, y + 1), index(x, y + 1))
 for y in range(vi) for x in range(vr)]
# Code to create a solid base
base = 0.0
pos = len(vertices)
pos_base = pos
vertices.append((p.real, p.imag, -base))
for x in range(1, vr + 1):
 vertices.append((p.real + x*d.real/vr, p.imag, -base))
 faces.append((index(x - 1, 0), index(x, 0), pos + x, pos + x - 1))
pos = len(vertices) - 1
for y in range(1, vi + 1):
 vertices.append((p.real + d.real, p.imag + y*d.imag/vi, -base))
 faces.append((index(vr, y - 1), index(vr, y), pos + y, pos + y - 1))
pos = len(vertices) - 1
for x in range(1, vr + 1):
 vertices.append((p.real + (vr - x)*d.real/vr, p.imag + d.imag, -base))
 faces.append((index(vr - x + 1, vi), index(vr - x, vi), pos + x, pos + x - 1))
pos = len(vertices) - 1
for y in range(1, vi):
 vertices.append((p.real, p.imag + (vi - y)*d.imag/vi, -base))
 faces.append((index(0, vi - y + 1), index(0, vi - y), pos + y, pos + y - 1))
faces.append((index(0, 1), index(0, 0), pos_base, len(vertices) - 1))
faces.append( tuple([i for i in range(pos_base, len(vertices))]) )
#code to create mesh and object and place the object in the scene
brot = bpy.data.meshes.new("Brot") 
mandel = bpy.data.objects.new("Mandelbrot", brot)
mandel.location = (0.0, 0.0, 0.0)
bpy.context.scene.objects.link(mandel)
#induce vertices, edges (empty list), and faces in the mesh
brot.from_pydata(vertices, [], faces) 
brot.update(calc_edges = True)
Advertisements

About heikkihietala

Heikki Hietala has worked at the crossroads of IT and language since 1986. He studied at the University of Jyväskylä, Finland. With an M.A. in English Philology and minor degrees in Communication and Information Technology, he has seen action at Microsoft, McKinsey & Company, Lionbridge, Bates Advertising and since September 2003, HAAGA-HELIA University of Applied Sciences. His interests of late have been user interface design and usability, 3D Design using Blender, and information technology for the small and medium enterprises. In his spare time he writes fiction in English. His novel, "Tulagi Hotel", was published in 2010 and a short story collection, "Filtered Light and Other Stories", in 2012. Tulagi Hotel is now available in Kindle and in paperback (also at Akateeminen Kirjakauppa), published by Fingerpress UK. "Hotelli Tulagi" on saatavana myös suomeksi kirjakaupoista kautta maan.
This entry was posted in 3D printing, Blender, hacking, tricks. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s