I've been interested in "quasicrystals" which are patterns that have long-term order but don't necessarily repeat. It turns out that they are pretty easy to generate using simple math. (Note "crystal" is used here in the mathematical sense of repeating patterns, not actual minerals!)
Here is the code. in both processing.org and OpenSCAD, to generate the solids that I printed: https://github.com/headrotor/quasi3D
Step 1: Generating Plane Wave Quasicrystals
While there are a huge variety of quasicrystals including Penrose tilings and X-ray diffraction patterns, the ones I'm using here are generated by summing plane waves. Imagine a sinusoidal plane wave: it looks like corrugated cardboard but extends to infinity. If you put a few of these together with the ripples at different angles and sum them all up, you get a quasicrystal. Here's a blog post that illustrates the idea. To see the kinds of patterns you can generate, I created some test patterns with different numbers of plane waves at different frequencies. Here, n is the number of different plane waves,: the left row is n=1 where there is only one sinusoid which is not very interesting. "f" is the frequency, or the number of waves that fit in the square. The top row shows f=1 where only one cycle fits in the box. As you proceed down, it is like zooming out as more and more cycles are visible.
The two images show sine waves (at the top) and cosine waves (at the bottom). Zero is at the center of the image, and plane waves are centered on that and rotated around it. Note that since sin(x) = -x the sinusoidal patterns are antisymmetric: the left half is the inverse of the right half. Cosine waves, on the other hand are symmetric: cos(x) = x so the cosine patterns at the bottom are perfectly radially symmetric.
Step 2: Generating Solids From Quasicrystals
I used Processing to generate a grayscale square png images of quasicrystals.
I used these as a height map to generate a 3D surface (really 2.5D, but we'll call it 3D). I used OpenSCAD to do that; it has a function surface() that given a grayscale image will loft it into a 3D surface. I looked at the zoo of patterns from the previous step, picked ones I liked (n=9, f=9) for both sine and cosine, then used OpenSCAD to generate quasicrystal 3D surfaces at the top of a round cylinder. I also used OpenSCAD to round the edges to make a nice tactile disk.
Step 3: Making Quasicrystal Solids
The basic 3D surface was not that interesting, so I experimented with some different ways to bring out the interesting structure in the 3D shape. Something that looked promising was to cut the surface out of a stack of thin slices. The resultant object would be striped like a topographic map of the terrain.
Because the Objet 3D printers I have access to at Pier 9 can print in different colors, I though I would try to fabricate some of these as an experiment. Making the solid models in OpenSCAD was a little tedious: it was straightforward to carve the surface from a stack of interleaved slices, but the resulting objects were so complicated it took several hours to render so I did not experiment too wildly.
I made four solids: two of the sine and two of the cosine pattern from the previous step. For the cosine pattern I printed a positive and a negative version: turned upside down, the quasicrystal surfaces mate perfectly. The sine pattern, because it is antisymmetric, is its own complement: I printed out two of the identical surfaces whcih mate perfectly when turned 180 degrees apart.
I was a little surprised by the resulting prints: the Objet Connex printers can print both black and white resins, but the layers were so thin some of the black pigment seeped into the white resin giving it a dark slate blue color. The overall effect was a little darker and morer restrained than the eyepopping black-and-white of the model, not sure that's a bad thing!
Step 4: Zebracrystals!
So I liked the wild stripy effects from the layered surfaces, but they were tedious to render in OpenSCAD. I decided to make the stripy surfaces directly, by using a sinusoidal palette in the grayscale images. This was easy in processing: to remap the brightness of a pixel with value v, I computed the sine sinv = sin(TWO_PI*w*v/(255.0)) then mapped the result back to 0-255 with int(map(sinv,-1,1,0,255)).
In the above equation "w" is the variable that gives the number of slices. Think of w as the number of layers in the surface that the quasicrystal is cut out of. This adds another dimension in our space of patterns to explore, so I again generated a whole bunch of crystals to see how things change with w. The first two images above are sine and cosine quasicrystals with f=7. The last two images are sine and cosine with the parameters f=7, n=5 and w=5, that is five stripes between the minimum and the maximum. These are the images I used to generate the surfaces for the shapes that follow.
Step 5: Zebra Quasicrystal Disks
Very similar to the previous step, I used OpenSCAD to generate the surfaces. Because they are not completely connected, they are a little tricky to print! Because I have access to Objet Connex 3D printers that can print in multiple materials, I decided I would print each shape surrounded by clear resin.
For each shape I rendered the quasicrystal surface, then I rendered another solid which was a disk with rounded edges with the quasicrystal subtracted. If these are printed together, the quasicrystal will fill the void in the disk and make a solid unit. I printed this out with black and white opaque resin surrounded by clear resin. This worked pretty well: the black gives you more contrast but the white makes more of the 3D structure visible. As an experiment, I printed out just the outside clear resin with nothing inside the quasicrystal void. The Objet printers can't print overhangs so they fill voids with a support material, which is what you can see inside the center disks in the last two images. The support material is clear but has a different index of refraction so it is visible, also it has a gridlike texture. I suspect the support material is not designed for longevity and may eventually yellow with UV exposure, but I still think it's a neat effect and I'm pleased with how it came out.