Simone Seagle

Simone Seagle

Independent Web and Educational Software Developer

Read More


Constellation Place Cards

Constellation Place Cards

July 11, 2019 Simone Seagle

Okay, buckle in because this is going to be a pretty long post. I wound up going pretty far in one direction before doing an about-face and doing something completely different. For the final version, you can skip to here.

This past month, one of my best friends got married. She's a brilliant astrophysicist currently at JPL, and her husband is a physicist at Brown. Their beautiful invitations featured a constellation theme, and as soon as I saw them, I texted her and said "Wouldn't it be cool if your table numbers were constellations too?" She said that she wanted place cards, and I basically bugged her until she would let me do it.

Being an overachiever, I decided the cool thing to do would be to write an algorithm to generate the letters uniquely every time it would run. I considered making a custom font, but that would be too boring because every e would look the same, and I considered doing them all by hand, but that would take forever. SO- algorithm it is. I settled on Processing because it is so easy to save pictures. For this project, I did not want to post the code online because I have a small hope that someone will pay me to make these again.

The first shot - Random Grid method

For my first pass, I tried separating each letter into sections and randomly populating each segment with stars, then connecting those stars with lines. I first select a font and print that font on the screen, white on black. Then I use Processing to determine which pixels are letters and which aren't. In order to get even coverage, I divided up each letter into sections. Unfortunately, this didn't really work out the way I had hoped. I realized it would actually be pretty tricky to make sure that the constellation lines were drawn properly instead of looking like a pile of junk, as you see below.

This is not what I wanted.

Can you guess what this even says? You probably can. Not acceptable for a wedding though.

Right now there are too many stars, and they're too uneven. If I take away the stars, the constellation lines don't draw properly. It's also difficult to ensure that the lines are connected the correct way for a letter to appear as you would expect. Then I decided to go for idea #2, which I call "inchworm."

The second shot - Inchworm Method

An inchworm.

Pictured: this algorithm trying to figure out where the next part of the letter is.

The idea behind this is a kind of path finding algorithm based on the letters themselves. The algorithm is like an inchworm. If you've ever seen one doing its thing, you know they kind of rear up and look around before taking their next step. This does the same thing. It starts at a pixel and does a fan shaped loop looking for the next star. The places are found by checking the brightness of the underlying pixel. If it doesn't find a new bright spot, then it stops. Unfortunately, this is one of the instances where something worked perfectly in my head, but didn't work at all in real life. I was able to basically get it to work, but it just couldn't seem to keep going as far as I thought it should.

Still not working.

And this still does not work.

However, while I was trying to get that algorithm to work properly, I stumbled upon the key to getting the first, admittedly less elegant, algorithm to work. After all, it doesn't matter how elegant my idea is if the damn thing didn't work. When I was deciding whether or not to jump to the next letter, I realized I didn't want to skip over too much black space. I did an average over the line from one star to the next to determine how light or dark it was. After hours of frustration, I realized this would save the grid method! All I had to do was check if the line was in bounds, and then I wouldn't have those nasty lines crossing where they weren't supposed to go!

  Boolean inLetterBounds(PVector start, PVector end) {
    float sum = 0;
    float d = dist(start.x, start.y, end.x, end.y);
    int numSteps = 25;
    int stepSize = floor(d/numSteps);
    float angle = atan2(end.y - start.y, end.x - start.x);

    for (int i = 0; i < numSteps; i++) {
      PVector v = PVector.add(start, PVector.fromAngle(angle).mult(i * stepSize));
      sum += brightness(get(int(v.x),int(v.y)));

    return sum/numSteps > 200;


Getting there...


Third shot- the Hybrid method

After finishing that, I realized the actual key was to COMBINE the random population method and the inchworm method by using the inchworm to connect the dots after they were created. This seemed to be the key, and I'm fairly happy with how it worked:

Good as it's going to get!

Not bad.

As a recap, I saved screenshots of each of the frames throughout the creation of the algorithm.

All the frames

Haha, just kidding, I'm going to paint them instead

And now we have the plot twist. After that, I realized that this whole exercise, while cool, was definitely not practical for a wedding. It was better to do just the table signs and the table lists. Jac and I came up with an idea to do it all based on specific constellations that were visible the night of the wedding when people were leaving. I came up with a list of six constellations, one for each table, and wrote a blurb about each one, creating matching table tents and table lists! The color of the constellation names matches her primary wedding color, which she told me was MILLENIAL PINK in all caps.

All of the backgrounds are unique and digitally painted. I've been really into that since I got a laptop with a pressure-sensitive stylus. Please don't tell anyone.

These are a couple of the lists, obviously with the names blurred out.

So much fun to work on!

This was a wonderful and satisfying thing to work on.

On each of the tables, there was a table tent. I made these to match the table lists. They're rotated 180 degrees so that they fold in half nicely and show the text on either side as an ice-breaker, and I wrote the text about each constellation myself using my somewhat-neglected planetarium skills. I can literally talk for hours about constellations- mostly because I was trained to, but also partially because they're delightful to talk about and have myriad great stories associated with them.

Planetarium skills!

My digital painting and planetarium skills combined.