Last year, we celebrated the release of FindExactCover with a fairly extensive art project post explaining how to make snowflake-inspired tiling patterns using all the 22 various weight-5 polyhexes. This post involved a combination of first-principles programming, mathematical analysis, and distributed computing (for results searching). Since the post had so much substance, we wanted to return to it in time for this holiday season, but not without taking the next step. This memo is completely on the other end of the user spectrum. Here we present a no-principles, quick-as-possible attempt to turn our previous data into something new and more exciting, a video with smooth frame transitions and melodic drum music in the background.
First we import the visual data of 25 different tiling patterns from the previous post:
In[]:=
graphicsData=
;
In[]:=
graphicsData[[1;;3]]//GraphicsRow
Out[]=
Then using AudioCapture and a Meinl A Major "Sound Energy" drum, we track a quick melody to put behind the animation:
In[]:=
audio=
Audio[
]
Out[]=
00:00
02:17
Data in CloudObject[
...8fea1fcd48
]
Next, we make a small computable dataset, and find a smooth order for frame transitions using FindShortestTour:
In[]:=
AbsoluteTiming[​​small=Rasterize[#,RasterSize->128]&/@data;​​]
Out[]=
{22.1008,Null}
In[]:=
ord=FindShortestTour[small,DistanceFunction->ImageDistance]
Out[]=
{275.596,{1,22,18,14,24,11,20,4,23,15,6,9,7,10,21,13,19,12,5,17,8,3,2,16,25,1}}
The shortest tour does noticeably better than a randomly chosen order:
In[]:=
Total[ImageDistance@@@Partition[small[[ord[[2]]]],2,1,1]]
Out[]=
275.596
In[]:=
Table[Total[ImageDistance@@@Partition[RandomSample[small],2,1,1]],5]
Out[]=
{320.283,325.609,318.862,317.375,323.347}
Finally, we compute large-size raster frames:
In[]:=
AbsoluteTiming[​​large=Rasterize[#,RasterSize->1024]&/@data[[ord[[2]]]];​​]
Out[]=
{25.0263,Null}
The large frames are needed as input to TimeSeries, which automatically computes linear interpolation between frames:
In[]:=
video=SlideShowVideo[TimeSeries[large,{0,2*60+17}]];//Quiet
All that’s left to do is generate and combine audio / video channels, export, and upload:
In[]:=
avout=VideoCombine[{video,audio}];
Export[NotebookDirectory[]<>"SnowflakeJam.mov",avout];//Quiet
https://www.youtube.com/watch?v=E2DTkSajfno
Fin!
Well, not quite. The PR team then tells me the frames need to go much faster than one breath, and the total duration can be only 30 seconds. The reason being that scrollers on social media have lost their patience. So we also need to make a promo by chopping the sound track, and speeding up the video frame rate:
In[]:=
video2=SlideShowVideo[TimeSeries[large,{0,30}]];//Quiet
In[]:=
audio2=AudioTrim[audio,-30.];
In[]:=
avout2=VideoCombine[{video2,audio2}];
In[]:=
Export[NotebookDirectory[]<>"SnowflakeJam30s.mov",avout2];//Quiet
https://www.youtube.com/shorts/SMEOcJLjeuY
Which version do you like better? Leave a comment below, or better yet, get the data and make your own remix. At it’s very basic level, the graphicsData contains individual polygon elements:
In[]:=
graphicsData[[1,1,1]]
Out[]=

,EdgeForm[Thickness[Tiny]],Polygon
Number of points: 20
Embedding dimension: 2

So it should even be possible to make tile-by-tile growth videos if you have a lot of extra time on your hands and you want to try something like what we did recently with the Aggregation Blog Post.
Happy Holidays, stay safe on the roads if they get iced over, and have fun!

CITE THIS NOTEBOOK

Ice-cold Snowflake Remix Jam​
by Brad Klee​
Wolfram Community, STAFF PICKS, December 12, 2023
​https://community.wolfram.com/groups/-/m/t/3082520