Thursday, December 12, 2019

Generating Sand Table Patterns Using Sandify

Update:  Sandify now minimizes edge and corner motion.  There's no need to use to clean up the gccode!  There are two levels of optimization.  The first, which is automatically applied, preserves the order of the pattern generation as did. The second level reduces edge and corner motion further by reordering the sequence of the lines in the drawing, which can have an impact on the way the final drawing looks. That level of optimization has to be activated by checking the "try to minimize perimeter moves" box on the "machine" definition tab in Sandify.

At the end of this post there's a link to the Trimify2x optimized pattern files presented here. I suggest you just grab the parameters from the patterns you're interested in and regenerate the gcode. Sandify's optimization is better than trimify2x.

Now back to the original post:

I recently posted about a program I wrote to optimize sand table patterns generated by Sandify.  If you're one of the 20 or so people on the planet who has built a sand table and uses Sandify to generate patterns for it, you may wonder why I wrote that program.  Why is there a need to "optimize" the pattern files?

If you have a square or round table, maybe you use sandify to generate patterns for it that look a lot like spirograph drawings, etc.  Maybe you limit the size of the patterns to something close to the size of your table.  In that case, there won't be a lot of excess motion around the edges of the table, and not much need for an optimizer that cuts out that type of motion.

I happened to build a table that is rectangular, with a drawing area of 710 x 1600 mm.  If I restricted patterns to fit in the center of the table, say 710 mm in diameter or so, it would leave a lot of empty space on the table.  So, from the start I have been making patterns that will fill up the entire table surface which means that they inevitably have a lot of motion at the edges of the table, because of the way Sandify works.


Shortly after I built the table, I generated patterns that were 30-40 cycles long and would take 10-20 minutes to finish and put together sequences of those patterns that would run for hours.  When you run patterns that way, you can usually see residue of the previous pattern in the new pattern drawn on the table.  Sometimes it doesn't look very nice.  I threw in erase patterns after every few patterns in the sequence, but it still wasn't satisfactory.

I started experimenting with patterns that ran for hundreds of cycles and often took over an hour to draw.  Those patterns often drew over parts of the pattern they drew earlier, but in this situation, it usually looks good because the new part of the drawing is similar to the old part and the transition is smooth.  If the pattern is going to take an hour to finish and it keeps drawing over itself, it looks really different every 10 minutes.  The problem with using high cycle count patterns was the amount of time the ball was spending at the edges of the table.  It's pretty boring to watch that type of motion because it isn't really contributing to the drawing.

That's what got me thinking about optimizing the patterns by stripping out all the unnecessary edge and corner to corner motion.  Now that the optimizer is written and working, I can generate patterns with very high cycle counts that extend well beyond the boundaries of the table knowing that the optimizer will take out all the "trash".

There are a few things that I do for every pattern.  I always home the machine before each pattern starts.  That leaves the ball at the lower left corner in all the images below.  I usually start the patterns along the bottom or left edge in the patterns below.  Sometimes that works out OK, but sometimes I have to save the pattern in reverse to get it to do that.  Once in a while, if a pattern wants to start along the top or right edge I will manually edit the file and add a couple G01 commands to move the ball to the starting point along those edges without crossing the table and leaving a track in the sand.

When you play with all the settings and let the patterns grow beyond the boundaries of the table, you can find some really interesting stuff:

One technique I use a lot is to start with a very large basic shape, then set the grow step to a negative value.  That will cause the pattern to get smaller with each cycle.  If you use a high enough cycle count, the pattern will shrink to zero and then start expanding outward again, but flipped in orientation.


A lot of the zig-zag lines come from playing with the track length and size.


Another source of interesting effects is to use a non integer number of sides or lobes for the different base shapes that are available.  Try a polygon with 4.3 sides or a star with 5.6 points.


Very often the Sandify preview looks quite different from the finished pattern on the table. In the example below, the messy looking stuff on the right side of the Sandify preview turns into the vertically oriented lines in the drawing.

The green ball along the top edge is the starting point of the pattern, and the red ball along the bottom edge is the end point.  The green squiggly line is the "track".

110219_7.gcode  Notice the ball is at the top edge- I must have saved this pattern in reverse so that the start would be along the bottom edge.
Another example- a lot of the messy looking stuff at the upper right corner is some of the first stuff drawn.  If this drawing were done in reverse, the messy stuff would be overwriting the "neater" later stuff.

The wandering back and forth in the pattern below is caused by using switchbacks.





Sometimes you get exactly what you'd expect from the Sandify preview:

The green ball on the left edge, below, indicates the starting point of the pattern.  The red ball near the center is the end point.  The green thing near the center is the "track" that is responsible for the waviness of the lines.  This pattern was saved as a reverse pattern so the start and end would be this way instead of the opposite.  If it started near the center, the ball would have left a track in the sand going from the edge to the center to start the pattern and that track would have shown up in the pattern.





The left side of the next two patterns look the same in the Sandify previews, but one pattern was saved in the forward direction and the other in reverse.




mishegoss1.gcode (not quite finished)

Some of these patterns look really good, even 3 dimensional, from an angle, too...

If you're interested in the settings I used to generate these patterns, you can DL a zip file, here, of the "clean" gcode (optimized by files.  Each file contains a header with the parameters used to generate the pattern.  You can enter those parameters into the appropriate boxes at and regenerate the same patterns (but use the dimensions of your own table).  If you regenerate the patterns, the file size will be much larger than those files that have been optimized by


Leave comments or a questions here and I'll try to post a response as soon as I can.