Creating Generative Art with D3
I recently took a trip to the SFMoma where I came across the work of Sol LeWitt. One of the interesting things about Sol’s work was that he created the rules of his art pieces, but they were executable by anyone. I wanted to see if anyone had recreated Sol’s pieces using D3.js. When I did a quick search I found that Chuck Grimmet had made some pieces which was really inspiring.
Nice d3js rendition of Sol LeWitt's Wall Drawing 86 by @cagrimmett - https://t.co/BaU46OxZmc pic.twitter.com/WOQZ2M0iOA
— Philip Davis (@philipcdavis) October 21, 2016
It got me interested in the idea of generative art. Generative art is not about communicating information. It’s about making visuals with instructions.
Recreating an art piece, in code.
I created this heart using Illustrator around 8 years ago. I wanted to see how difficult it would be to create something similar using D3.js. I was looking for a technique that allowed me to create this effect using any SVG path.
First, I created a grid of SVG circles and colored them using a scale from color brewer.
I love how easy it is to generate pretty things with #d3js. pic.twitter.com/m40mQJHRK6
— Philip Davis (@philipcdavis) January 4, 2017
Next, I imported a SVG path and tried to detect whether the center of a circle was inside the path. I found lots of ways to do this with polygons, but I wasn’t able to find a solution for SVG paths. Thankfully, I found a canvas method called isPointInPath that allowed me to do what I wanted.
❤️ Getting closer. Canvas has a handy method for detecting if a point is inside a path. Couldn't find for SVG: https://t.co/ckggydyFC6#d3js pic.twitter.com/GpBtuDXPcE
— Philip Davis (@philipcdavis) January 5, 2017
❤️ Next Step is to get this Mitchell's best candidate example to fill in an arbitrary path. https://t.co/cksIDOrpnk #d3js pic.twitter.com/kjC5aqf3VL
— Philip Davis (@philipcdavis) January 5, 2017
This effect was really great on its own. But it’s not what I wanted for this piece. I didn’t want an even grid of circles. I wanted it to look like a human placed the circles.
I came across Mike Bostock’s example of Mitchell’s best candidate in his article on visualizing algorithms and realized it would be the perfect fit for the task. This algorithm takes a number of random coordinates, and then chooses the best candidate based on whatever point is farthest from all the others.
Using this algorithm, and help from one of Mike’s examples I was able to get my final result.
I’m happy with it, but there are two problems I would love to have solved.
The first being the ability to detect whether or not a point is inside a path using SVG. Canvas is fine, but there are certain things I’d like to do with animations that are harder using canvas.
The second thing would be the ability to prevent circles from escaping the bounds of the path. Right now, i’m only checking the center of the circle to make sure it stays within the path. There’s probably a way to detect that the area of the circle hasn’t escaped the path but I haven’t found it yet.
Explorations
One of the side benefits of working on generative art in D3.js is that you discover new portions of the API. Below i’ve collected some of the things i’ve made this month.
Example of Custom Arc Tweening.
Live
Example of Using D3.js transitions.
Live
Generating Static
Working with Radial Lines.
Live
If you’re interested in learning D3.js, check out my full course. It’s a concise and comprehensive guide to the D3.js library. I’d also love to hear from you if you have feedback or resources to share.