Skip to content

Generate animated gifs of quasicrystal patterns using sums of waves in the plane

License

Notifications You must be signed in to change notification settings

makeyourownmaker/QuasicrystalGifs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

67 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

QuasicrystalGifs

Lifecycle python

Generate animated gifs of quasicrystal patterns using sums of waves in the plane with python

If you like the quasicrystal scripts/notebooks, fork the repository and contribute or, give it a star!

Usage

Assuming you have python in your path and all dependencies installed:

python quasicrystals.py -fn qc.gif

Here is the generated gif:

The above command will generate an animated gif called qc.gif with the following default main settings:

Name Short Long Description Default
Waves -wa --waves Number of waves in the plane 5
Stripes -st --stripes Number of stripes (or periods) per wave 37
Iterations -it --iterations Number of frames in animation 30
Delay -de --delay Number of microseconds between animation frames 8
Resolution -rs --resolution Image size in pixels 512
Colormap -cm --colormap Colormap from matplotlib PiYG
Log-polar -lp --log_polar Use log-polar coordinates instead of Cartesian Cartesian

And with the following default light source illumination settings:

Name Short Long Description Default
Blend mode -bm --blend_mode Blend mode for light source - one of {soft, overlay, hsv} None
Azimuth -az --azimuth Azimuth for light source measured clockwise from north in degrees 0
Elevation -el --elevation Elevation for light source measured up from zero plane of the surface in degrees 90
Vertical exaggeration -ve --vert_exag Ammount to exaggerate or de-emphasize elevation values by when calculating light source illumination 1

All of the above arguments are optional.

Setting the waves option to 4 or 6 will produce an animation but it will not be quasiperiodic. No warning is given.

A colormap is a matrix of values that define the colors for graphics objects. All the matplotlib colormaps are supported but I've not tested all of them. Here is a list of the matplotlib colormaps.

Here is the matplotlib light source documentation. It's possible to de-emphasize and lose the rotational symmetry when adjusting the light source settings. The default azimuth and elevation settings specify a light source directly above the plot.

The only required argument is -fn or --filename.

Name Short Long Description
Filename -fn --filename Filename for animation

The filename must use the gif file extension and should not use any sub-directories.

There is one more optional argument:

Name Short Long Description Default
Quiet -q --quiet Turn off messages False

Check the -h or --help options for further details like acceptable values for each command line option.

Installation

Requires:

To install the two python packages:

pip install -r requirements.txt

After the above dependencies have been installed simply download and run the script:

wget https://raw.githubusercontent.com/makeyourownmaker/QuasicrystalGifs/master/quasicrystals.py
python quasicrystals.py -fn qc.gif

Alternatively, clone the repository and run the script:

git clone https://github.com/makeyourownmaker/QuasicrystalGifs
cd QuasicrystalGifs
python quasicrystals.py -fn qc.gif

Details

What are quasicrystals?

A quasicrystal, or quasiperiodic crystal, is a solid material that is intermediate between an orderly crystal and an amorphous glass. They resemble crystals because they are composed of repeating structural units but they incorporate two or more unit cells into a quasiperiodic structure. A unit cell is the smallest group of atoms which has the overall symmetry of a crystal. Quasicrystal patterns or ordered but not periodic and can continuously fill all available space, but lack translational symmetry.

Classic crystals can possess only two, three, four, and six-fold rotational symmetries; as seen in their diffraction patterns. The diffraction patterns of quasicrystals show peaks with other symmetry orders.

Quasicrystals can be thought of as the 3 dimensional generalisation of a Penrose tiling.

How does this quasicrystal animation work?

Each frame of the animation is a summation of five or more waves at evenly-spaced rotations. That is, every point in each animation frame is colored according to the sum of sines and cosines depending on the x and y coordinates. The animation is determined by an evenly-spaced orientation angle between 0 and 2 * pi. The number of wave cycles in the animation is determined by changing "stripes". Larger numbers of stripes leads to finer structures.

This method is known as the dual method. It is related to de Bruijn's multigrid method which can be used to create aperiodic tilings. For an n-fold rotational symmetry the multigrid consists of n sets of parallel lines with equidistant spacing, which are rotated against each other by 2 * pi / n radians. The stripes parameter specifies the number of parallel lines in each set and the waves parameter specifies the rotational symmetry. The quasiperiodic table of waves and stripes below shows some static examples.

The equation of the kth grid line in the jth set is:
equation of kth grid line in jth set
where σ_j is an offset of the jth set of lines in the direction normal to the lines.

The quasicrystals.py script uses this equation to calculate values at x and y coordinates.

Note: The generalised dual method (GDM) uses quasiperiodic grids, i.e. sets of parallel lines with spacings from a Fibonacci chain. It is a method for generating quasicrystals with any orientational symmetry (distinct angles between waves) and creates a wider variety of space filling patterns than other methods. The GDM is not currently implemented in the quasicrystals.py script.

Examples of quasicrystals

The first synthetic quasicrystal, a combination of aluminium and manganese, was reported by Dan Shechtman and colleagues. Shechtman won the 2011 Nobel Prize in chemistry for this work.

Icosahedrite is the first naturally occuring quasicrystal to be found. It has the composition Al_63 Cu_24 Fe_13 and was discovered in a meteorite by Luca Bindii and Paul J. Steinhardt.

A holmium–magnesium–zinc (Ho–Mg–Zn) quasicrystal has the shape of a regular dodecahedron, with 12 five-sided faces.

Hundreds of quasicrystals have been confirmed. They are often found in aluminium alloys.

Limitations

These quasicrystal patterns don't have well defined lattice points, so are not exactly quasicrystals.

The bottleneck in generating the animated gifs is the final step, saving them. This involves a surprisingly large amount of data transfer. See this stackoverflow answer for more details. Note: the quasicrystals.py script uses PillowWriter instead of ImageMagick which saves a few seconds.

The -q or --quiet option will disable the Saving progress animation and reduce runtime a little.

If you start having time or memory problems converting animations to gifs then try using a black and white or greyscale colormap:

# Short options
python quasicrystals.py -q -fn qc.gif -cm binary

# Long options
python quasicrystals.py --quiet --filename qc.gif --colormap binary

Other black and white/greyscale colormaps include: binary, gist_yarg, gist_gray, gray and Greys.

Reducing the resolution is also helpful:

# Short options
python quasicrystals.py -q -fn qc.gif -cm binary -rs 400

# Long options
python quasicrystals.py --quiet --filename qc.gif --colormap binary --resolution 400

Reducing the number of animation frames is also beneficial:

# Short options
python quasicrystals.py -q -fn qc.gif -cm binary -rs 400 -it 20

# Long options
python quasicrystals.py --quiet --filename qc.gif --colormap binary --resolution 400 --iterations 20

Gallery

Log-polar coordinates with default settings (see table above):

# Short options
python quasicrystals.py -fn qc.gif -lp

# Long options
python quasicrystals.py --filename qc.gif --log_polar

python quasicrystals.py -wa 7 -st 128 -rs 800 -cm spectral -fn wa_7_st_128_rs_800_cm_spectral.gif

python quasicrystals.py --waves 7 --stripes 128 --resolution 800 --colormap spectral --filename wa_7_st_128_rs_800_cm_spectral.gif

python quasicrystals.py -wa 7 -st 128 -rs 800 -cm hsv -fn wa_7_st_128_rs_800_cm_hsv.gif

python quasicrystals.py --waves 7 --stripes 128 --resolution 800 --colormap hsv --filename wa_7_st_128_rs_800_cm_hsv.gif

python quasicrystals.py -fn qc_gray.gif -cm gray

python quasicrystals.py --filename qc_gray.gif --colormap gray

python quasicrystals.py -fn qc_ls_hsv_gray.gif -cm gray -bm hsv

python quasicrystals.py --filename qc_ls_hsv_gray.gif --colormap gray --blend_mode hsv

You can also browse through the gifs in the figures directory.

Quasiperiodic table of waves and stripes

This table shows what combinations of waves (wa from 4 to 14 in steps of 2) and stripes (st from 2 to 12 in steps of 2) look like:

st = 2
st = 4
st = 6
st = 8
st = 10
st = 12
wa = 4 wa = 6 wa = 8 wa = 10 wa = 12 wa = 14

Roadmap

  • quasicrystals.py:

    • Simplify handling of log-polar transformation
    • Allow specifying both width and height of images
    • Add generalised dual method
    • Permit defining arbitrary orientational symmetry
      • Arbitrary angles between waves
      • Translational order will decrease
    • Include direction of rotation option
      • Currently defaults to anti-clockwise
    • Consider up, down and left, right scrolling
    • Consider zooming out animation
  • Expand README:

    • Add more examples to gallery
      • Particularly light source illumination examples
      • List command line arguments used for each animation
    • Describe log-polar transform instead of using Cartesian coordinates
      • Add figure
    • Describe rotational and translational symmetry of quasicrystals
      • Add figure
    • Add figure explaining dual method
  • Add Jupyter notebook(s):

    • Add links to run notebook(s) on NBViewer, MyBinder and Colab

Alternatives

Quasicrystals as sums of waves in the plane is the earliest implementation I've been able to find. In Haskell.

Another early implementation. This time in Java. Requires post-processing with the convert tool from ImageMagick to produce animated gifs. Code is readable but not vectorised. Additional code. More recent work.

Quasiperiodic designs by Peter Stampfli. Including quasiperiodic designs from superposition of waves from 2012 Also, http://geometricolor.ch/ which is a browser app for creating quasiperiodic wallpapers. https://github.com/PeterStampfli/images

Andrew Horchler's Matlab implementation will produce animated gifs or movies.

Mads Ohm Larsen's python gist which also requires ImageMagick post-processing.

Trevahok's python implementation has no external dependencies. Generates static greyscale images but code is short and very readable.

Mike Bostock's Javascript and WebGL implementation is editable in the browser.

Quasicrystals on shadertoy by multiple authors.

Program to make quasi-crystalline patterns in C from 1995. Generates static postscript files. See How to make a quasicrystal for an explanation of quasicrystal tiling.

Processing and OpenSCAD code to generate 3D quasicrystal solids. 3D printed results and tutorial

See Also

Quasicrystals on Wikipedia

The Second Kind of Impossible by Paul Steinhardt describes the authors adventures searching for quasicrystals from meteorites in Siberia while dodging KGB agents and much more.

Quasicrystals and Geometry by Marjorie Senechal starts with the history of crystallography and then covers methods for generating aperiodic tilings.

Alan Mackay predicted quasicrystals in a 1981 paper

Quasicrystalline Medieval Islamic Architectural Tilings

Diffraction pattern of a penrose tiling

Greg Egan's deBruijn tiler Javascript applet

Eugenio Durand's QuasiTiler from 1994 No source code.

de Bruijn's original Penrose tiling papers:

  • de Bruijn, N.G. (1981). "Algebraic theory of Penrose's non-periodic tilings of the plane. I". Indagationes Mathematicae (Proceedings). 84: 39–52. doi:10.1016/1385-7258(81)90016-0.
  • de Bruijn, N.G. (1981). "Algebraic theory of Penrose's non-periodic tilings of the plane. II". Indagationes Mathematicae (Proceedings). 84: 53–66. doi:10.1016/1385-7258(81)90017-2.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

License

GPL-2