This post was first published on CoderHood as Generating Art With Code: Doodling, Math And Cornucopias. CoderHood is a blog dedicated to the human dimension of software engineering.
I have a compulsive need to create art; I also have a lifelong love for coding. The two passions are compatible and interrelated. Coding and Math can generate artistic visions. In this post, I show how I created a program to draw doodles formed by tangles of "Cornucopias" swimming in space.
If you are a reader of my blog, you know that every Tuesday I publish a hand-drawn meeting doodle from my Moleskine. Recently I have been doodling an interesting shape that, for some reason, I enjoy looking at. I call it a cornucopia because it resembles an elongated and twisted goat horn. You can see an example here.
This week Doodle is based on that concept, but it is a bit different and much more elaborate. Here it is:
As you can probably guess, I didn't draw this with a pen and paper. I wish I were that good. Instead, I "drew it" with code and math, and I am going to show you how I did it.
During the holidays, in between eggnog and Christmas cookies, I decided to do a little side project to keep my coding skills sharp and satisfy my compulsive artistic urges. I created a Processing (pretty much Java) sketch to automatically generate art pieces composed by cornucopias floating in 3D space.
I started off with a clear vision of what the final result had to be. My intent was to convey a sense of motion and a sense of "entanglement." I also wanted to generate many random variations of the doodle to have material to make a selection for the most visually pleasing one. Additionally, I tried to make the code easily very configurable.
A cornucopia as defined in this context is probably a bit different than what you'd expect. It is a 3D shape generated by extruding a spiral along a Bézier spline.
A spiral is defined by the position of its center, a small radius r, a large radius R > r, an angle alpha, a number of FULL loops L >= 0 and an angle beta.
Here is an example with r=1, R=2.5, alpha=-30°, beta=60° and L=3:
You can also eliminate the need of having both L and beta by simply specifying an angle theta = (360*L)+beta. In the example above, theta = 1140°.
A cornucopia is a 3D shape, and it needs some "thickness." To create it, I simply doubled the spiral by drawing two spirals with the same r (or close to the same), alpha, beta and L, but slightly different values for R. Here is an example:
After removing the labels from the image, the shape of the spiral becomes clearer:
A cornucopia extends through a path following a Bézier Spline, that is a curve that intersects a given number of points in space. The following is a 2D example of a spline defined by 8 points:
The cornucopia starts with a large head and ends with a narrow tail; it kind of resembles a trumpet. After playing with various formulas, I settled for an exponential radius, which results in a shape with a section like this:
Finally, the cornucopia is formed as the result of an extrusion of a spiral along a spline in 3D space. Imagine stretching a spiral along a spline and creating a trumpet-like shape with an exponential radius from head to tail.
Here an example rotated in various directions:
The Doodle Generator uses all of this "theory" to create an image with a large number of random cornucopias oriented with the head in the general direction of the observer. The program also allows the selection of a texture image to finalize the effect to a pleasant composition and the positioning of the lighting source.
I showed you an example of the final product at the beginning of this post; let me show you a few more.
One with a single texture texture:
And one with multiple textures:
The source code of the result can be found here.
Note: Processing sketches are generally not applications designed to be used by non-technical people. They are usually compact pieces of code built with the sole purpose of generating images or animations. My Cornucopia Art sketch is not an exception, and changing its parameters requires changing the code.
This is a work in progress that I will continue to refine over time, especially if there is interest in the topic.