Programming – Interlocking Exponential Circles
- If you’re not a programmer, you can download the software here. Run the exe, load the sample SVGs, play around, and feel free to skip the details in the rest of this post.
- If you are a programmer and want to follow along, or think you can improve this software, please do! The source is available here .
So… I decided I would make another cabinet (post coming next week!). And then, messing about in CAD, I realized I could create cool patterns with parametrically related circles. The only issue was the sheer number of cascading parametric relationships – each circle related to the circles touching it – managed to crash my machine. Even my beefy video-editing desktop. The easiest solution would be to change the design, but I was infatuated to the point I fell asleep thinking about circles every night…
So I dove in, assuming I’d figure it out as I went. The first challenge was to describe the actual expansion I was looking for… I knew I wanted the pattern to grow both in circle-radius and circle-spacing, but couldn’t really describe it better than that. So forget it! We’ll come back to it. Instead, I wrote a program that would create a list of circles on a grid. Just X, Y, and radius. A couple nested for loops that spat out a list of numbers.
Now we need to turn those numbers into circles. I looked at a few graphic libraries for c#, but I wanted an output format I could drop into cad. I really wanted a DXF. So I checked out some DXF libraries, and started reverse-engineering DXF files. Reverse-engineering is really just a fancy term that means “I changed the extension to TXT and looked at it notepad”. This still looked like a lot of work. What about SVG? I use Inkscape for cad more than I should… some of Doomba’s mechanical parts even went straight out of Inkscape to SendCutSend.
Success! There was a lot of complicated file definition, but when I drew a SVG of a single circle, I saw a single corresponding line of code in notepad.
<ellipse style = “fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.24600001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1″
id = “path652″ cx = “8″ cy = “8″ rx = “5″ ry = “5″ />
Do I know what all these fields mean? Nope. But playing with cx and cy showed them to be center-x and center-y, and rx/ry were radiuses (two options for ellipses, but we’re sticking to circles so we’ll use the same number for each).
So now, I can have my program spit my list of circles into an actual SVG! It starts by copying the beginning of the SVG, adds a line for each circle – updating cx/cy/rx/ry, and then appends the tag that closes the document. Then save it as an SVG, and done! On top of that, I had GPT help me look up parts of the code for me… GPT works very well as a stack-overflow research engine.
Now my program can draw circles! Which means I could start playing with the variables to figure out how to create the pattern I was looking for. I could do a lot of math… but it was faster and more fun to play guess-and-check. So much guess-and-check I had to optimize the program. I added more and more options for circle locations, spacing, and sizing. But with this many variables, I would forget the settings I used. So I had the software save the last set of variables. But that didn’t solve the problem for previous circles, so I added a comment to each SVG containing all the variable values used in that SVG. On the flip side, I wrote a function that will extract those variables from a saved SVG, so it was easy to tweak a design that was almost right.
This is another section where GPT did most the work… I wrote sample code showing how it would work for one-variable, and then told chat GPT to duplicate that code for each of a long list of variable names, changing the data-types to match the definition. AI is excellent at what boils down to a multi-step copy-paste problem, and probably saved me a few hours over the course of this project.
After hours of guess-and-check, the equations ended up being:
double locX = deltaX * Math.Pow(expX, x – 1);
double locY = deltaY * Math.Pow(expY, y – 1);
double distance = Math.Sqrt(x * x + y * y);
double circleRadius = circleSize * Math.Pow(circleFactor, distance);
Better, I had a SVG. I dropped this in Inkscape where I could overlay it on the outlines of the doors I’d drawn. I resized the circle-array, and mirrored it for the opposite door. Export to DXF, load it into Aspire (one trick here: use “Quick Engrave” to engrave only the lines, without the CAM software worrying about which regions over overlapping shapes are positives or negatives). Export to .SBP, and off to the shopbot!
Success!