Saturday, December 21, 2013

Visualizing a Fractal with a 3D Printer

I purchased a Printrbot Simple a few weeks ago with the hope to make something cool and unique with it.  I did use it to print some Christmas ornaments for my family, which was a good way to break it in.  I really wanted to model something myself and have it just appear in real life.  The 3D printer is a nifty bridge between art and engineering.

Specifically, I want to do two things with the device: create something no one has seen before, and experiment with different textures as a medium or a means to augment the qualities of an artistic piece.  I think it would be interesting to see someone take a two dimensional piece and apply texture to it, so that the piece takes on different qualities when seen from different angles.  That's sort of what I'm doing here, but something I'd like to explore further some day.

One thing that I've wanted to do for awhile is visualize the Mandelbrot fractal in three dimensions.  If you are not familiar with the Mandelbrot fractal, you can read about it here.  To summarize, it's a set of numbers on the complex plain such that when you continuously square and cube the numbers, it does not diverge into infinity.  This very simple equation leads to incredibly interesting and complex designs.  The more you zoom into a projection of this fractal, the more interesting it becomes:


I imagine that most people exploring the fractal for the first time experience it as a colorful space that you can zoom through in a simulated space ship.  I wanted to know what it would look like as a mountainous landscape, and I wanted to see it in real life.

I set out to generate a 3D model of what the fractal looks like, with the Z axis representing "the number of multiplicative iterations before the point on the complex plane assuredly escapes into infinity."  This is how the fractals are usually colorized.

The first step was to find a section on the complex plane to visualize.  This was the most fun part.  I just used a section from Wikipedia for now:



I started with code to visualize the fractal as an image.  I used a modified version of this script to generate my "reference image:"

The image intentionally looks like a spooky X ray of some amoeba.  It has to be black and white - we're only dealing with three dimensions here!

Now I had reached the hard part: translating this image into a solid mesh.  This is where existing software really helped me.  I used Blender, an free 3D modeling and animation suite.  Blender allows you to create meshes using Python scripts.  Perfect.  First I tried calculating the fractal right in Blender as I generated the mesh.  This proved to be an impractical way to tweak the parameters.  So I wrote a script to read back the image and create a mesh to visualize the image with the pixel brightness as the Z axis.  (Scripts can be found here)

Here is what my generated mesh looks like in Blender:


Interesting!  A few details: I first used a Gaussian blur on the reference image to make it less "spikey".  I also upped the contrast a bit on the reference photo so the outer designs were more visible.  Finally I didn't bother orienting my face normals in any direction, so I had to use Blender's Mesh->Normals->Recalculate Outside function.  This gave me a solid mesh I could export to an STL.

Here's the model on Thingiverse: http://www.thingiverse.com/thing:209974/

I imported the STL into RepetierHost (which took about 20 minutes) and calculated the G code with Slic3r (which took another 30 minutes).  This gave me time to warm up and calibrate my bot.

Here's the final outcome:






Control an RC Car Over the Internet

A few months ago I set out to make an RC car controllable over the internet.  I hosted a website from my laptop to make this happen.  This is what you would have found on the about section if I left the site up (the car was getting a bit annoying).  Source code can be found here


Real RC Race was a project to get an RC car controllable over the internet. I started at my local Radio Shack and bought the cheapest RC car I could find [1], as well as a breadboard, some transistors and LEDs.

I searched the internet for "control rc car from computer" and the first source I found was this [1]. This guy used a parallel port to run current on a circuit that flipped switches on an RC car's controller. At first I tried using a parallel port. Living in 2013, I did not own a computer with a parallel port. I bought a USB parallel port only to find that the microcontroller in the adaptor would provide an abstracted interface to the operating system, preventing one from physically setting bits on the wire like you could on an old school parallel port. One adventurer [2] used a transistor to latch the values written to the port on his USB adaptor, but this setup seemed unreliable.

I broke apart the car's remote control and soldered wires from the remote's switches to the breadboard. I also grounded the remote's batteries to the breadboard. From here I could control the car with copper wires. I set up 2N3904 transistors to gate these connections, as well as LEDs to show current was going through, and verified with a AA battery that I could use external power to control the car. The circuit remains roughly the same today.

Finally I resigned to make another investment and purchase an Arduino Uno. This was a breeze to set up, program and use. In a matter of minutes I was controlling the car using my keyboard through the Arduino's handy serial interface. I put 1K resistors and LEDs between the Arduino's digital pins and transistor gate. Originally I used the remote's AA batteries to power the antenna, but later connected the Arduino's +3.3V to a handily visible positive terminal on the remote, saving the need to replace its batteries in the future. The Arduino sketch is found below under "sauce". It's extremely straightforward.
Next I wanted to control the Arduino using Java. This wasn't terribly difficult; I found out that the Arduino IDE uses RXTX to communicate with the board and I grabbed a copy of this library. I had a Java program writing data to the serial port using RXTX.

Finally there was the the task of running a Java server to talk to the board, and a client application willing to talk to it. At first I tried using standard Java Sockets and an applet in a webpage to connect to it. I had a server and console application client talking to each other using sockets and controlling the car. However, it turns out that building and signing an applet on Linux is not easy. I didn't care to write an entire applet anyway, and I don't think anyone really enjoys running an applet in a webpage.
There had to be an easier way to do this. I tried to see if I could just set up a raw socket connection to my server from JavaScript. It turns out you just can't do this, but you can come close with WebSocket [4]. Java EE provides WebSocket support, but attempting to install the Java EE SDK on my Linux laptop resulted in my screen turning blank. So I decided to go with jWebSocket [5]. This library works, but I think it was written by apes and the documentation is abysmal. Regardless, that's what I used in my project.

With a WebSocket connection to my controller server from a webpage, I was controlling the car from any computer. For the webcam I used Motion [6], which magically sets up a web server running on 8081 that shows a stream from your webcam. I just used my laptop's webcam.

Anyway, I hoped you enjoyed this story. All of my code is found below and you're free to view, copy, modify and use it, barring any restrictions from the dependencies I used. If you want to copy this project entirely, you'll have to acquire the hardware I described, and install jWebSocket, RXTX, Motion and Python (for the static web server) on your machine. I used Linux but I'm sure this setup will work on any platform. Cheers.
  1. http://www.radioshack.com/product/index.jsp?productId=16767136
  2. http://www.jbprojects.net/projects/rc/
  3. http://www.linuxquestions.org/questions/linux-hardware-18/usb-parallal-adapter-i-o-trickery-836663/
  4. http://en.wikipedia.org/wiki/WebSocket
  5. http://jwebsocket.org/
  6. http://www.lavrsen.dk/foswiki/bin/view/Motion/WebHome