Workshop on Functional Art, Music, Modeling and Design

Wearing my PhD-student hat, I’m helping organize a workshop, FARM, to be held in Boston this September. I thought it worth mentioning since some readers of this blog—especially those interested in the intersection of math, art, and programming—may find it interesting. The focus of the workshop is essentially using beautiful code to produce beautiful artifacts—whether art, music, or anything else. If that sounds interesting to you, you should consider submitting a paper, or planning to attend! See the website for more details.

Posted in meta | Tagged , , , , , , , , | 1 Comment

Making connections

Here’s something fun I was playing around with today. I generated 100 random points and connected some of them with lines. Can you figure out how I chose which lines to draw?

How about these? (Same points, different lines.)

Or these?

Here are some more. The first three groups in the grid below correspond to the pictures already shown above.

Posted in challenges, geometry | Tagged , , , | 10 Comments

Animated Sieve of Eratosthenes

Here’s something I made yesterday! (Note, I strongly suggest watching it fullscreen, in HD if you have the bandwidth for it.)

Can you figure out what’s going on? The source code for the animation is here; I was inspired by Jason Davies’ visualization which was in turn inspired by this.

Posted in arithmetic, counting, pattern, pictures, primes, video | Tagged , , , , | 11 Comments

Stars of the Mind’s Sky with Diagrams

A few weeks ago, Paul Salomon posted a really beautiful work of mathematical art on his blog, Lost In Recursion:


Stars of the Mind’s Sky, by Paul Salomon

He included a precise mathematical description of the image, and I naturally wondered how difficult it would be to replicate using the diagrams framework which I wrote about previously.

The answer: not hard! All told it is only about 30 lines of code, give or take. So I decided to exhibit it here, both as a way of explaining the cool math behind Paul’s image, and as a way of showing off the power of diagrams to do this sort of visualization and mathematical art.

This post is literate Haskell—you should be able to copy and paste the contents of this post into a file with an .lhs extension, and run and play around with it yourself. First, some requisite imports and such:

> {-# LANGUAGE NoMonomorphismRestriction #-}
> 
> module SOTMS where
> 
> import           Control.Arrow                  ((***))
> import           Data.Colour.SRGB
> import           Data.Colour.RGBSpace
> import           Data.Colour.RGBSpace.HSV
> import           Diagrams.Backend.Cairo.CmdLine
> import           Diagrams.Prelude

Star polygons

The image is primarily composed of a bunch of star polygons, the figures you get when you take p points evenly spaced around a circle and connect every qth point. For example, here’s what we get when we pick p = 12 and q = 5:

I’ve numbered the vertices to make it easier to see how vertex k is always connected to vertex k+5 (modulo 12) by a line segment. Vertex 0 is connected to 5, which is connected to 10, which is connected to 15 = 3, and so on.

In this example, we get one continuous polygonal path which cycles through all the vertices. But sometimes we get several disjoint paths. For example, below is what we get with p = 12 and q = 3. I’ve used distinct colors to make it easy to see the three separate squares:

If you connect every third point out of twelve, you come back to where you started after hitting only four points, so three separate square paths are needed to connect all the points. Given values for p and q, can you say in general how many distinct paths result? Here are a few more examples to fuel your investigations:

In fact, the number of separate paths needed to draw a given star polygon is how Paul chooses the color: red for star polygons that are one continuous path, yellow for two paths, blue for a lot (that is, 24), and shading gradually from yellow to green to blue for numbers in between. (Now that you know this, you might want to go back and study the image again, looking for patterns!)

There’s one thing left: what about q = 0? This is a sort of “degenerate” star polygon where we don’t connect any of the points. Paul chose to draw those using just dots for the vertices, like this:

In Paul’s image you can see these going in a straight line from the center to the top, though it’s a little hard to see what’s going on since they all overlap with each other.

Drawing star polygons

So, let’s see some code already! First, a simple function to generate the kind of regular polygons we want:

> -- Make a regular polygon with n sides and radius r, oriented with
> -- one vertex pointing in the positive y direction.
> regP n r = polygon with { polyType   = PolyRegular n r
>                         , polyOrient = NoOrient
>                         }
>          # rotateBy (1/4)

Now, we define a function mkStar which takes p and q as inputs and draws a (p,q)-star polygon, coloring it according to Paul’s color scheme:

> -- If q = 0, draw a bunch of dots at the vertices of a regular polygon
> mkStar n 0    = decoratePath (regP n 1) (repeat (circle 0.1 # lw 0))
>               # fc (colorByNumber n)
> 
> -- Otherwise draw a star polygon
> mkStar n skip = let p        = star (StarSkip skip) (regP n 1)
>                     numPaths = length . pathTrails $ p
>                 in
>                     p # stroke # lw 0.08 # lc (colorByNumber numPaths)

Incidentally, the coloring scheme was the only part that wasn’t specified in Paul’s post, so I hacked something together using trial and error and the “eyedropper” tool in GIMP. I also have to go to a bit of trouble to blend from yellow to blue in HSV space, so it looks like this:

and not in RGB space, which looks like this:

You need not pay too much attention to this code, but I’m including it here for completeness. (I plan to soon include some extra tools in diagrams for helping manipulate colors, which would make this a lot easier to accomplish.)

> paulRed    = sRGB24 0xDA 0x22 0x22
> paulBlue   = sRGB24 0x4C 0x89 0xC0
> paulYellow = sRGB24 0xD1 0xB3 0x41
> 
> colorByNumber 1 = paulRed
> colorByNumber c = hsvBlend (min 1 ((fromIntegral c - 2)/10))
>                     paulBlue paulYellow
> 
> hsvBlend t c1 c2 = uncurryRGB sRGB . hsv3 $ lerp h2 h1 t
>   where
>     [h1, h2] = map (hsvView . toSRGB) [c1,c2]
>     fst3 (x,_,_) = x
>     hsv3 (h,s,v) = hsv h s v

The final colors don’t look exactly like Paul’s original image but they’re close enough.

Orbits

Now that we can generate individual star polygons we have to put them together into “orbits”. All the star polygons in a particular “orbit” (that is, at a particular distance from the center) have the same value of p (that is, the same number of vertices). The star with q=0 is at the top, and then the stars for other values of q progress in order around the orbit. (Quick quiz: does the value of q increase going clockwise, or counterclockwise?)

Making the stars around a particular orbit is easy: we create all the stars (map (mkStar n) [0..] will make one star for each value of q), and then place them at the vertices of a radius-(n-1) regular n-gon using decoratePath.

> stars n = decoratePath
>             (regP n (fromIntegral n - 1))
>             (map (mkStar n) [0..])

For example, here are the outputs for stars 6 and stars 7:

Finally, each orbit is shown with a faint circle, so we make an orbit function which returns the stars and associated circle together:

> orbit n = ( stars n
>           , circle (fromIntegral n - 1)
>             # lc (blend 0.95 white black)
>             # lw 0.08
>           )

Putting it all together

Finally, we generate the orbits from 2 to 24 and draw them all! Note that we have to draw all the orbit circles first and then the stars, because we don’t want any of the orbit circles getting drawn on top of the stars. This is what the funny business with unzip, uncurry atop, etc. is doing.

> starsOfTheMindsSky = uncurry atop
>                    . (mconcat***mconcat)
>                    . unzip
>                    . reverse
>                    . map orbit
>                    $ [2..24]
> 
> main = defaultMain (starsOfTheMindsSky # centerXY # pad 1.1)

And here’s Paul’s original version for comparison. Pretty close!

I love all the different patterns you can see in this work of art—close inspection and thinking really pays off as you discover more and more interesting structure. For example, this could really make a wonderful activity for a class—you could buy a print from Paul, put it up, and see what the students find!

Incidentally, I have also really been enjoying Paul’s “imbalance problems”, here, here, and here—go check them out!

Posted in geometry, group theory, pictures, programming | Tagged , , , , , | 9 Comments

Book review: Guesstimation 2.0

Guesstimation 2.0: Solving Today’s Problems on the Back of a Napkin
Lawrence Weinstein

I got a review copy of this book, and initially decided I wasn’t going to review it—I hate those sorts of consulting-company-interview estimation problems, you know, like “what percentage of all the shampoo bottles in the world are in an airplane at this moment” or “how much poop does the San Diego Zoo produce per year” or whatever.

But I picked it up in an idle moment and found myself spending far longer reading it than I had intended. Weinstein is clearly a master estimator, and anyone actually interested in estimation will find a wealth of information here. In addition to working out the solutions to many estimation problems, it also includes lots of advice about estimation in general. But what I enjoyed most is his fun writing style and his quirky choice of questions, like “how much fuel would airlines save if they required all passengers to urinate before boarding?” (as, apparently, Nippon Airways began doing in 2009, though I imagine not actually for fuel efficiency reasons), or “how many bullets does it take to cut down a tree?”, or “which has more mass, the air or the brains in a movie theater?” (Answers: not much, about ten thousand, and the air by a factor of ten.) He is also able to leverage physics to estimate answers to lots of interesting questions that would never show up in an interview, because they’re so difficult to get a handle on otherwise, like “how far away can you detect a candle on a clear, dark night?” So even though I probably won’t end up using any of the techniques myself, it ended up being a fun book nonetheless.

Posted in books, computation, review | Tagged , , , | Leave a comment

Diagrams!

Over the past few years I’ve written quite a few posts with images generated by a library I (now along with many others) wrote. Most famously, this is how I created those factorization diagrams. But I’ve used it in many other posts as well (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16). I promised to write a post explaining how it works and (more importantly) how you can use it too—and here it is!

About diagrams

My library is called diagrams (a rather generic but nicely descriptive name). As I hope to show you—and as I hope you can see from the above list of posts—it’s really nice for doing all sorts of visualization, for mathematical exploration, and even for creating art with a mathematical bent. It’s not a program for creating images (like Illustrator or Inkscape), but actually a language for describing what you want your images to look like. What makes it really powerful is that it is actually “embedded” in the Haskell programming language—that is, diagrams programs are Haskell programs, written using stuff provided by the diagrams library. To do simple things with diagrams doesn’t actually require knowing much (if any) Haskell, but the full power of Haskell is available to do more sophisticated things.

So, what can it do? Of course, you can make simple shapes like circles, squares, triangles, pentagons, and so on:

> dia = circle 1

You can also make crazier shapes like stars:

> dia = stroke $ star (StarSkip 2) (pentagon 1)

You can specify attributes like fill and line color, line width, or line dashing:

> dia = myStar # lw 0.05 # lc purple # fc yellow # dashing [0.1,0.05] 0
> 
> myStar = stroke $ star (StarSkip 2) (pentagon 1)

Note in the above example how you can make arbitrary definitions and then reuse them.

You can apply transformations like translation, rotation, scaling, and reflection:

> dia = myStar # scale 2
>   ||| myStar # rotateBy (1/19)
>   ||| myStar # reflectY # translateY 0.5
> 
> myStar = stroke $ star (StarSkip 2) (pentagon 1)

You can compose multiple diagrams into one by putting them on top of each other or next to each other:

> dia = (circle 1 <> circle 2 <> circle 3) ||| (square 2 === triangle 2)

You can already create some cool pictures just using the above features—and you don’t really have to know any Haskell! But bringing the power of Haskell into the picture lets us accomplish much more. I’ve written about Haskell several times before; if you want to learn more about it, check out Learn You a Haskell. To whet your appetite, here are a few simple examples.

Haskell has a built-in notion of lists. We can create lists of diagrams and lay them out using operations like hcat:

> dia = hcat [ circle n # fc blue | n <- [1 .. 5] ]

We can also create shapes from arbitrary paths described using lists of points or vectors, or use paths to position other diagrams:

> myPath = fromVertices [ 0 & 0, 0 & 2, 0.5 & 0.5, 2 & 0 ]
> 
> dart = myPath # close # stroke # rotateBy (-1/6)
> 
> circles = decoratePath myPath (repeat (circle 0.2))
> 
> dia = dart ||| strutX 2 ||| circles # centerXY

We can write recursive functions to generate diagrams:

> sierpinski 1 = triangle 1 # fc black
> sierpinski n = s === (centerX (s ||| s))
>   where s = sierpinski (n-1)
> 
> dia = sierpinski 6

There are also a ton of existing Haskell libraries available on http://hackage.haskell.org/, and we can seamlessly integrate any of them with diagrams—though I don’t have a good example off the top of my head.

Installing diagrams

If you’d like to play around with it, here’s what to do. The first step is to install the Haskell Platform. Once you have that installed, open a terminal/command line, and type

cabal install diagrams

then go get a snack because you might have to wait for a while. But after it finishes you should have diagrams installed! Now take a look at the tutorial and the gallery of examples, and start playing!

Learning more

After you have finished the tutorial (which really only scratches the surface), there is also an extensive user manual which covers (almost) everything you could want to know about diagrams. If you have questions, there is a mailing list and an IRC channel (#diagrams on freenode). You’re also welcome to leave questions as comments on this post.

Last but not least, if you’re interested in seeing how it’s all implemented, or even contributing to the project, the source code is all available on github.

Posted in links, pictures, programming | Tagged , | 1 Comment

Penrose tiles on my refrigerator!

I got some Penrose refrigerator magnets in the mail the other day! They look nice on my fridge, don’t you think?

Here’s a close-up:

(Unfortunately, since this was just a Kickstarter project there’s no way to order more at this point.)

There are just two types of tile (ignoring the colors), both quadrilaterals, one a “kite” shape with three angles of 72 degrees and a fourth angle of 144 degrees, and the other a “dart” shape with angles of 36, 72, 36, and 216 degrees. You can use them to completely tile the (infinite) plane with no gaps or overlaps—and in a way that is aperiodic. By that we mean that the tiling has no translational symmetry, that is, there is no way to translate the tiling so that it matches up with itself. In fact, if you follow a couple simple rules in the way that you are allowed to put the tiles together, it forces the resulting tiling to be aperiodic. Pretty cool! Though as I learned from playing with the tiles, you can’t just put the tiles together any way you like, even following the rules—sometimes you get stuck and have to backtrack to find an arrangement that works, which makes it a rather engaging little game. (In fact, now that I look at it more closely I think I made a mistake in the picture above—can you spot where the tiling is going to go wrong?) Though you can no longer get them as refrigerator magnets for now, you could certainly cut your own tiles out of card stock or something like that.

The Wikipedia article on Penrose tilings has a lot more information about this and related tilings.

Posted in geometry, pattern, pictures | Tagged , , , , | 6 Comments