↖️ Blog Archive

Sunrise PCB Art, Part One

Bradley Gannon

2025-09-04

TL;DR: I burned myself out a little on my self-playing piano project by working on it all summer, so I’ve decided to switch to a weekly rotating project schedule. To help clear my mind, I’ve begun building a little art piece made out of some single-sided FR4. This has prompted me to learn more about how to use Inkscape, how Bézier curves work, and some of the details of the SVG standard.

Changing How I Organize My Projects

I spent the summer working on my self-playing piano, which was fun at first but became unexpectedly challenging and frustrating. I learned a lot and still intend to finish the project, having overcome a lot of the problems I found in the summer, but I need a break before I can do that. I also realized towards the end of this iteration of the project that I should reconsider how I allocate my time for them. Right now, I choose a project, set a rough goal and end date, and then work on it more or less exclusively until one or the other arrives. I started doing projects this way in order to give myself some structure and encourage actually getting to the end. Previously, as soon as a project got difficult, I’d switch to something else. Selecting a project and working on it for a longer period on purpose was a good way to avoid this issue.

It turns out that this method can burn me out if I work on something too hard or for too long. I overestimated my progress on the piano project at the start of the summer, so a lot of my frustration came from uncovering the lurking problems with my design and “catching up” to where I thought I already was. This is likely to happen again if I continue with this approach. It also makes it difficult for me to react to changes in my own interests on shorter time scales.

I’ve decided to adopt what I call the Usagi model of personal project management, which I’ve stolen from David at the Usagi Electric YouTube channel. His method is to maintain a list of around four projects and cycle between them on a weekly basis. When a project finishes, a new one takes its place. Sometimes a one-off project will displace another one for a short time. He claims that it reduces burnout and helps to maintain a high level of interest in the projects over the course of years. I like this idea because it directly addresses the problems I’ve encountered with my current system. It also reminds me of a round-robin timesharing system that you might find in an older computer operating system. Maybe that’s where David got the idea.

I still plan to write a big post about my piano work over the summer, and then the piano project will take its place among the four normal slots in my rotation. I’ll spend my next piano “time slice” on writing the post and ordering any additional parts, and then the next slice in a few more weeks will be the first one where I get back to actual engineering. That should be plenty of time for me to recover from this minor burnout. I also plan to write weekly posts corresponding to each project period (like this one), which should make them shorter and easier for me to write.

Sketching and Planning

My wife suggested that I try to make some of my projects under this new system about art, and I think that’s a good idea. I don’t have much skill in most of the traditional art disciplines, but I think it’ll be healthy for me anyway because it’s harder to completely fail to make art. I had an idea for a sunrise picture knocking around in my head, so I sketched out a few ideas and then drew it up in Inkscape.

Black pen on white paper sketch of a sunrise, with the spaces between the rays shaded in
A large copper-colored disc at the bottom of the frame with several rays
extending from it towards the top

Initially I wanted to cut up some bits of wood on my new CNC mill and then apply different stains to separate the two colors, but I decided against it because the cutting depth for most of my end mills just isn’t deep enough to work with the lumber I have. I could resolve this by just getting thinner pieces of wood, but I realized I could use some spare single-sided FR4 I had laying around from the piano project and potentially get a better result. The shiny copper will represent the sun and its rays, while the fiberglass on the back will be the sky, which explains the unusual colors in the SVG. I’ll cut the pieces and glue them all together on an MDF backing board.

It was fun to learn a bit more about how to use Inkscape for non-trivial work. It’s a really powerful program for this kind of stuff, and I only understand a tiny fraction of its features.

The Kerf Problem

Kerf is the width of the cut that a tool makes. Rather than simply splitting the material into two pieces with no loss, most mechanical cutting tools take tiny bites out of the material and spit it out as chips or dust. It’s important to account for kerf when planning cuts. If you line up a cutting tool with the center of a cut, then half of the tool width will eat into each side of the cut path, leaving you with two pieces that are shorter than you might have wanted.

For this project, I need to tell my CNC mill how to make several closed loops in such a way that it cuts out the shapes I want. If I feed the paths in the above SVG directly into svg2gcode, then I’ll end up with shapes that are all half a tool width too small. Instead, I need to offset the tool by half a tool width in the “outward” direction for all paths and cut along that path. The tool will sort of “roll” along the edge of the desired shape. The kerf isn’t eliminated, but it’s fully inside the waste area of the material that I’m going to discard anyway.

The general problem of finding offset curves is interesting and sometimes difficult. Because they show up all over the place, lots of software can compute them in one form or another. For my projects, I like to try to find non-GUI solutions since they can be automated more easily. This increases my iteration speed by allowing me to make tiny changes, run make or whatever else, and get new output immediately without clicking around and maybe forgetting something. I searched around for an easy way to compute offset curves for either SVG paths or G-code, but I couldn’t find what I wanted. It seemed like I would need to do it myself.

In this case, it’s okay to approximate the offset curves as sufficiently small line segments, rather than finding mathematically perfect solutions. Since SVG paths are a sequence of several different possible parameterized subpaths, an algorithm can convert the path description into a list of points with some geometry. This polygonal path is just the kind of thing that the Clipper2 library is good at handling, and it’s a particularly good fit for me because it has Rust bindings and an inflate method that computes the offset path exactly how I want. I was hoping to avoid figuring out how to compute the offset path (even from a point list) because of annoying problems like “which of the two normal vectors points in the outward direction?” and “how do I handle extreme concavity?” Clipper2 sweeps that all up for me as long as I can provide it a list of points.

The SVG path language is somewhat complex and has some edge cases that I didn’t expect. There also doesn’t seem to be a Rust SVG parsing library with the higher-level features that would make this problem easy, so I had to build out the “path to point” logic myself based on the svg crate. I was able to get by with just line segments for now by doing some manual path management in Inkscape (mainly subdividing and straightening). I also used this tool to debug my code and convert to absolute coordinates. These last bits kind of break my intention of doing everything with command line tools, but at least in principle I could work towards that with my new tool in the future.

The code is here. The tool is called svg-kerf, and it reads and writes on stdin/stdout for maximum pipe-ability.

For now, the code is good enough to work with the above SVG as input, producing chunkier versions of the same paths that (I think) are ready to be sent to svg2gcode. Next time around I’ll try to get the artwork done and then use the rest of the time to make improvements to the svg-kerf code.