// Sketch Link //
For this weeks assignment, I attempted to recreate one of the shots from the Jelly Car video where the word “SPRINGS” is spelled out with soft body letters.
I began this task by expanding upon our soft body sketch created in class and made a square soft body with two inner springs to support the body (a technique I learned from the video).
I thought that was easy enough! How much harder could it be to draw some letters!?
Turns out it’s pretty hard…
I realized the letters would have to be drawn as a series of points. And so, I wondered how to come up with those points without having to play a huge guessing game of measurements. I decided to use Figma to trace the letters and use the Figma point coordinates to come up with x,y points for my sketch.
This worked well! I was able to get the points of the letter S drawn in p5. It, however, took a long time as I was going to each point individually and copying the coordinates into my sketch.
I decided to worry about this later (as I had 6 more letters to draw) and continued on trying to figure out how to turn these points into a soft body.
I went through the array of particles and added springs connecting each point. This worked, however, my letter was collapsing!
I tried using VerletConstrainedSprings
instead of the normal springs, thinking that would fix the problem, but it did not. I realized I needed some form of inner support structure of springs to hold the S up (just like the square from earlier!).
I played around for a while as to how to do this, and came up with this algorithm:
The steps are basically as follows:
- Go to each particle in the array of the particles
- For each particle A in the array, run through the array again and see if any particle B is within a certain distance of particle A
- If so, create a spring between A and B
- If not, skip that particle and continue on
And it works!
I learned later on there are some issues with this, but we will get to those soon.
I added code to draw the lines connecting each point (so that we may actually see the letter) and added a debug mode that draws the generated springs.
Here, you can see what the letter S looks like using the aforementioned algorithm.
I added some color and things were looking good! I still, however, had six more letters to complete and was not about to copy and paste each individual coordinate into p5. So, I came up with this workflow to speed up the letter creation process (and simplify my p5 project)
- Trace the Letter in Figma
- Export the trace as an SVG
- Convert the SVG to x,y coordinates using this converter
- Take that result and use this sketch I wrote to convert it into an array of points
- Copy and paste that result into my sketch in an array
And it worked! Instead of needed 23 individual lines of code to draw the letter S, it was condensed into this:
This also made uploading the next five characters (there are two S’s) much faster. This is, unfortunately, where I began to run into problems with my spring code.
If you’ll notice, in the gif above, the letter S has a very tight, symmetrical shape meaning that there are plenty of points of connection for springs. A letter like r, however, has a long stem that consists of only a few points. This meant that using my spring algorithm, the letter would instantly collapse and not be strong enough to support itself.
You could just increase the radius of spring creation but this leads to another problem where way too many springs are created and the sketch begins to lag.
So, I decided to rewrite the spring algorithm…
In the new algorithm, there is now a second array of inner particles (innerParts
). This array is a copy of particles
but has the particles immediately before and after particle A removed (as those connections have already been made). Basically, if Particle A does not meet the minimum required connections, the search radius increases until it does.
The steps are as so:
- For each Particle A, go through the
innerParts
array - If Particle B is within the search radius
- Add a spring between particle A and particle B
- Remove Particle B from
innerParts
- If
j
is at the end of the loop and the number of connections is less than the minimum amount- reset j and increase the search radius
The code seem to work relatively well, sometimes weird connections are made and changing the minimum connections number does not appear to affect much so I probably wrote some part of it wrong.
I would love some suggestions on how to improve this or if there is a way to generate actual support structures in soft bodies! (like below)
At one point, I tried drawing all the springs in the shape and then uploading them as a seperate vector list but this ruined the p5 beginShape / endShape code I was using. I’m sure there is some way to fix this though.
I stopped playing with the algorithm, wrote a letter class to simplify things, and added the rest of the coordinate lists. And now we arrive at my finished simulation:
It does not look perfect and there is some weird movement in the bodies but I think it is still fun! Also, I find it cool that this code is theoretically expandable to any SVG file as it auto generates the springs needed for the soft body support skeleton.
In the future:
- Figure out better skeleton structure algorithm
- Ability to drag and drop letters around
- Collisions? 🤨