WOLFRAM NOTEBOOK

Streams July 27 and July 29 2024

By twitch.tv/physbuzz and chat.
Note: This notebook was made on a livestream, and so not everything is written in stone or thoroughly fact checked!
Keep in mind that it’s meant as a record of what we did on stream and a repository of source code, so it’s not a pedagogically sound well-written document!

Old code + Description of what I’m trying to do

The starting points are these images, coded in late 2022. This notebook is all about the work involved in animating them!
Out[]=
The images visualize flow fields. So they’re best interpreted as orange particles moving on the surface of water, with a motion blur filter applied to the picture. SO the obvious thing to do would be to let the particles move over time and animate it that way. Unfortunately this will require a lot of work!
P.S. Expand the image cell above see the code that generates them.

Other fluid flow stuff:

If we want to find the position of the orange particles as a function of time, we could use the same formulas used in Aubrey Jaffer’s webpage on fluid marbling patterns. https://people.csail.mit.edu/jaffer/Marbling/Mathematics . But I’m going to do this from scratch + explore!
In[]:=
V=1.0;L=0.2;scalarFunction[{x_,y_}]=Sin[Sqrt[x^2+y^2]10];strokeTransform[{x_,y_}]={x,y+VExp[-Abs[x]/L]};wavyTransform[{x_,y_}]={x+0.05y^2,y};wavyTransformInverse[{x_,y_}]=({x2,y2}/.Solve[Thread[wavyTransform[{x2,y2}]=={x,y}],{x2,y2}][[1]]);Rasterize[DensityPlot[scalarFunction[wavyTransformInverse[strokeTransform[wavyTransform[{x,y}]]]],{x,-3,3},{y,-3,3},MaxRecursion->5],ImageSize->{256,256},Background->Transparent]
Solve
:Solve was unable to solve the system with inexact coefficients. The answer was obtained by solving a corresponding exact system and numericizing the result.
Out[]=

First pass at new code

Making a Translating Image

First, let’s just get a translating image which uses the same orange and black color scheme:
In[]:=
width=64;height=64;color[t_]={0,0,0}t+(1-t)List[0.91,0.5,0.17];ClearAll[translatedImage];baseArray=Table[color@RandomReal[],{j,1,height},{i,1,width}];translatedImage[amount_]:=translatedImage[amount]=Image[RotateRight[#,amount]&/@baseArray];
We get a translating random orange and black image:
In[]:=
Manipulate[translatedImage[k],{k,1,width,1}]
Embedded gif for viewing on the Wolfram cloud:

Gif generating code

Passing them into Line Convolution

To start with, let’s just use these frames as input to LineConvolutionPlot. It won’t end up generating good results, but it’s a start.
In[]:=
g[z_]=Log[z];nframes=2;imgTableFirstPass=Table[LineIntegralConvolutionPlot[{Re[Grad[g[z]/.zx+yI,{x,y}]],translatedImage[Floor[widthframe/nframes]]},{x,-1,1},{y,-1,1},EvaluatedTrue,FrameFalse,ImageSize64],{frame,0,nframes-1}];//AbsoluteTiming
Out[]=
{15.6814,Null}
With just two frames it’s hard to tell what’s going on in the animation:
In[]:=
Row[imgTableFirstPass]
Out[]=
But with the full .gif it’s easier to see what’s going on, and it’s easy to see that passing a translating image into the LineIntegralConvolutionPlot function doesn’t do what we want!

Trying something else!

Any approach like this will just result in boring translations.
So I have to use the formulas that Jaffer uses: https://people.csail.mit.edu/jaffer/Marbling/Mathematics
A few approaches to figuring this out...
  • Work out the transformations by hand (something
    likez(t)=
    2
    z
    0
    +2it
  • Try it a hacky way first
  • The Hacky Way:

    So like I said at the start, the ideal animation would be one that actually tracks the motion of fluid particles over time. We’re not gonna do that, we’re just going to try something that tries to fake the animation.
    I’m going to start by trying to animate this image:
    Let’s just do a hacky way by doing a coordinate transformation that looks like the following. I transform the pixel image from square coordinates like on the left, to cylindrical coordinates like on the right:
    Out[]=
    Im using the ImageTransformation command. The texture on the left is indexed by
    (u,v)
    coordinates with
    (0,0)
    being the top left and
    (1,a)
    being the bottom right. I want to define a map such that...
    (0,v)|->(0.5,0.5)
    (the left side of the image gets mapped to the center of the new image)
    (1,v)|->(0.5,0.5)+1(Cos[const*v],Sin[const*v])
    (the right side gets mapped to a circle)To figure out the constant, we have to decide on
    (1,0)|->(0.5,0.5)+1(1,0)
    (1,a)|->(0.5,0.5)+1(Cos[const*a],Sin[const*a])
    const =
    2π
    a
    The forward transformation is this:
    In[]:=
    forwardTransform=({1,a}/2+#[[1]]{Cos[#[[2]]2Pi/a],Sin[#[[2]]2Pi/a]})&
    ImageTransform needs the inverse of this transformation, and that’s going to be a pain to figure out!

    Figuring out the inverse transform:

    Note: at the end of the day this is just transforming back and forth between cylindrical and Cartesian coordinates, and I’m really doing it a very dumb way here. This is more of a “using a sledgehammer to crack a walnut” solution.
    The inverse transformation is:
    Note: ArcTan has a range [-Pi,Pi], so I’m just going to add Pi to it.
    If we were thinking deeply about this problem, we could check that this formula is consistent with our requirements for the forward transformation. But let’s skip that and just use the formula!

    Getting a simple animation

    Still frame:
    Embedded gif:

    Putting LineIntegralConvolution plot over it:

    So, beforehand we put translating images into LineIntegralConvolutionPlot. Now we’re going to put this expanding animation into LineIntegralConvolution plot. We can try it with different vector fields.
    The single source looks quite boring:
    Putting an obstacle in the way looks cooler:
    A dipole looks the coolest:

    Doing it the correct way (?)

    Okay, so the cheating way gives us cool images but maybe we should just do it the correct way from the beginning.
    We did a bunch of math:

    Checking formulas are correct:

    These two formulas should be equivalent:
    Equation on the righthand side says:
    So we’ve proved that the equation is correct, in general it looks like we’ll have nasty implicit functions in the solution.
    ^ IMO this demonstrates that we’re not going to get useful formulas in an easy way!

    Key takeaway

    Revert to numerics the only option?
    I guess so! Time to implement things in Shadertoy or experiment with specific setups in Mathematica, but I can’t do a fast and general render in Mathematica.

    The correct way but for a specific case

    I can’t end it there! We didn’t solve for a general g, but let’s at least make a plot solving for the g=log(z) case. This section is very hacked together code. I just wanted to get something done!
    So we have a function that maps {x,y} to some other point {x(t),y(t)}.
    We have a point {x,y} and a time t and we have to decide on a color.
    {x,y} should take its color from F[x,y,t].
    Let’s use a funny image for our input:

    Tangents

    Making a gallop sound in Mathematica

    I mentioned that the MIDI sounds in Mathematica are really good now, for example we can make a gallop pretty easily. In this very quick example, “b” is short for “beat”, “r” is short for “rest”, and “h” is short for “high”.
    In a future stream, I’d like to imitate the Bells of Bezelea which is on LCOLONQ's stream.

    Viewer Question: When does a^m make sense for square matrix m?

    Some scratchwork related to that:

    Recall the identity:
    Writing the matrix expressions:
    Checking for 2 to the identity matrix.
    Checking for 2 to the 2x2 matrix of ones:
    Checking for 2 to the {{0,1},{-1,0}}:
    Another fun idea: Can we make a QR code out of the flow field images?

    Computational physics portfolio project:

    mewondering6’s question: what should i do, what projects, languages, should i analyze the job market and learn the language that is most asked for?
    My answer: It’s highly dependent and I’m not quite the best person to ask, but I can certainly suggest good projects!
    One good project is this beautiful wave simulator project by 0x23: https://github.com/0x23/WaveSimulator2D
    The code is really short, the updating of the image is done in six lines of Python! (handled in update_field in source/wave_simulation.py)
    Nils Berglund, who has similar projects but written in C, also posts his source code publicly: https://www.youtube.com/watch?v=-RJ0Y1EDJZY

    dr_cook_’s recommendations and Clifford algebra stuff

    Animating Spherical Harmonics

    We got distracted talking about nice animations of something like hydrogen atom orbitals. White this isn’t exactly a hydrogen atom orbital, this is still a very cool project and it can be done very quickly.
    First I define random sums of spherical harmonics, and I superimpose three wavefunctions on the sphere with frequencies of 1, 1/2, and 1/3. (So the total period is T=2*pi*lcm(1,2,3)=12*pi):
    Then I define a plot function. These options are my preferred way of animating! SphericalRegion would be especially important if we wanted the camera to circle around the rotating ball, but with a stationary camera I suppose it isn’t necessary. Likewise I ignore ColorFunctionScaling, we can do all of our color function scaling ourselves.
    And finally, outputting a .gif:
    “DisplayDurations” can also accept a list argument:

    Combining the frames into a cool table:

    Combining the frames in a cool way:

    Stylesheet Work

    Dark mode

    For stream, I use the dark mode stylesheet by Jakob Neef: https://gitlab.com/jakobneef/mathemeatica
    Removing the stylesheet at the end of the day:

    Thinking about gif embedding:

    Manipulate is too annoying to get working on the web
    ListAnimate works but has huge filesizes
    So I guess I’ll just WebEmbed .gifs for everything.

    Next Stream Idea:

    Implement Bells of Bezelea using SoundNote: https://pub.colonq.computer/~bezelea/bells/index.html
    Talking with dr_cook_:
    Minutephysics visualization using Blender + atomic orbital irreps (writing to .blend files from Mathematica would be easy... right?)
    Illustrations of river coordinates (Gullstrand-Painleve)
    Get code working to easily create small .gifs and compress them.

    What did we accomplish this stream:

    Organization work on the July 27th stream,
    Figured out how to embed .gifs in web notebooks,
    Experimented with .gif creation,
    Met some people + got some ideas for future streams (more spherical harmonics, minutephysics visualizations, exporting to Blender from mathematica)
    Wolfram Cloud

    You are using a browser not supported by the Wolfram Cloud

    Supported browsers include recent versions of Chrome, Edge, Firefox and Safari.


    I understand and wish to continue anyway »

    You are using a browser not supported by the Wolfram Cloud. Supported browsers include recent versions of Chrome, Edge, Firefox and Safari.