Belousov-Zhabotinsky sun catcher

A forum for topics that don't fit elsewhere. Introduce yourselves to other members of the forums, discuss how your name evolves when written out in the Game of Life, or just tell us how you found it. Forum rules still apply.
Post Reply
User avatar
pcallahan
Posts: 953
Joined: April 26th, 2013, 1:04 pm

Belousov-Zhabotinsky sun catcher

Post by pcallahan »

Generated in a Python script with a hexagonal neighborhood and 120° symmetry, die-cut in two colors of acetate, and embedded in clear resin.
20230801_113853.jpg
20230801_113853.jpg (504.78 KiB) Viewed 21776 times
I realized after making a similar one that I could get three colored bands by cutting filters for adjacent bands and using the combination as the third color. This makes it possible to cut the filters at a higher level of detail. This is an 86mm disk and would be quite fragile otherwise and hard to remove from the cutting mat without breaking it. I made a small mistake and left islands in the red filter. I will add bridges for them when I make another.
20230731_093949.jpg
20230731_093949.jpg (203.34 KiB) Viewed 21776 times
Here you can see them casting a colored shadow. It does that in resin as well, but with less clarity.
20230731_093721.jpg
20230731_093721.jpg (223.93 KiB) Viewed 21776 times
User avatar
otismo
Posts: 1599
Joined: August 18th, 2010, 1:41 pm
Location: Florida
Contact:

Re: Belousov-Zhabotinsky sun catcher

Post by otismo »

Do you have .rle 's for any of your Patterns ?

They must look great as colorful C. A. 's ...

Thank You !
"One picture is worth 1000 words; but one thousand words, carefully crafted, can paint an infinite number of pictures."
- autonomic writing
forFUN : http://gol.jct.onl
ArtGallery : http://cgolart.onfav.net
VideoWS : http://conway.life
User avatar
pcallahan
Posts: 953
Joined: April 26th, 2013, 1:04 pm

Re: Belousov-Zhabotinsky sun catcher

Post by pcallahan »

otismo wrote: September 16th, 2025, 7:42 am Do you have .rle 's for any of your Patterns ?
I generated them with floating point calculations on a 2D array so they're inherently dense. The same code could generate a series of images to animate, I think, but I never tried. I'll see if I can find it and post it.
User avatar
pcallahan
Posts: 953
Joined: April 26th, 2013, 1:04 pm

Re: Belousov-Zhabotinsky sun catcher

Post by pcallahan »

otismo wrote: September 16th, 2025, 7:42 am Do you have .rle 's for any of your Patterns ?
Here's what I was able come up with. First, the Python code, which is mostly taken from elsewhere (with acknowledgments).

Code: Select all

import math
import numpy as np
from scipy.ndimage import convolve
from sys import argv
from PIL import Image

# Simulation method modified from https://scipython.com/blog/simulating-the-belousov-zhabotinsky-reaction/

# Side length of base rhombus (stored as an nXn grid)
n = 200 if len(argv) < 2 else int(argv[1])
# Value for all Belousov-Zhabotinsky reaction coefficients. 
param = 1 if len(argv) < 3 else float(argv[2])
# Number of interations to run.
niter = 500 if len(argv) < 4 else int(argv[3])

# Reaction parameters.
alpha, beta, gamma = param, param, param

# Shape of hexagonal neighborhood out to radius 3.
FILTER_STR = '''
1111000
1111100
1111110
1111111
0111111
0011111
0001111
'''
FILTER_INT = [[int(c) for c in row] for row in FILTER_STR.split()]
FILTER = np.array(FILTER_INT)/sum(sum(row) for row in FILTER_INT)

def update(p,arr):
    """Update arr[p] to arr[q] by evolving in time."""

    # Count the average amount of each species in the neighborhood around each cell
    # by convolution with FILTER
    q = (p+1) % 2
    s = np.zeros((3, arr.shape[2], arr.shape[3]))
    for k in range(3):
        s[k] = convolve(arr[p,k], FILTER, mode='wrap')

    # Apply the reaction equations
    arr[q,0] = s[0] + s[0]*(alpha*s[1] - gamma*s[2])
    arr[q,1] = s[1] + s[1]*(beta*s[2] - alpha*s[0])
    arr[q,2] = s[2] + s[2]*(gamma*s[0] - beta*s[1])

    # Ensure the species concentrations are kept within [0,1].
    np.clip(arr[q], 0, 1, arr[q])
    return arr

def equivalence(i, j, n):
  """Find the equivalent coordinates in the base rhombus by rotating through symmetries."""
  rot = 0
  while True:
    if ((i // n) + (j //n)) % 3 == 0:
      return i % n, j % n 
    i, j = -j - 1, i - j
    rot += 1

# Initialize the base rhombus with random amounts of A, B and C.
data = np.random.random(size=(2, 3, n, n))

# Build a 3nX3n patch based on 120-degree rhombic packing.
# This can be tiled with simple toroidal wrapping at the boundaries.
arr = np.zeros((2, 3, n * 3, n * 3))
for i in range(arr.shape[2]):
  for j in range(arr.shape[2]):
    ti, tj = equivalence(i, j, n)
    arr[:, :, i, j] = data[:, :, ti, tj]

# run the iteration
for i in range(0, niter):
  arr = update(i % 2, arr)

# Create an image from just the top nXn square, equivalent to the base rhombus
disp = np.concatenate((arr[(i + 1) % 2].transpose(2, 1, 0)[:n, :n, :], np.full((n, n, 1), 1, dtype=np.uint8)), axis=2)
img = Image.fromarray((disp * 255).astype(np.uint8), mode='RGBA')
w, h = img.size
img = img.transform((int(w * 3), int(h * math.sqrt(3))),
                    Image.Transform.AFFINE, (0.5, 0.5 / math.sqrt(3), -0.5 * w, 0, 1 / math.sqrt(3), 0),
                    resample=Image.Resampling.BICUBIC) 
img.save('/Users/calla/Downloads/zb3a.png')
img.show()
You can see how I modified it for a hex neighborhood to get the symmetry I wanted. This is an image I generated with it. It's a rhombus with periodic conditions when rotated.
zb3a.png
zb3a.png (218.31 KiB) Viewed 1908 times
I went into GIMP to fit three of these together with 120 degree rotations. I wasn't too careful about lining up the boundaries. I think I have code that does this part automatically anyway.
hex.PNG
hex.PNG (627.63 KiB) Viewed 1908 times
That's a hex tile that can be repeated without rotation and will cover the plane with a continuous Belousov-Zhabotinsky pattern. You could use it as wallpaper. Too bad the 60s are over because it might be in demand as a psychedelic backdrop.

You can generate a series of images like this to animate and I believe it will show the reaction dynamically. I was only interested in an image to use as a suncatcher so I never tried that.
User avatar
pcallahan
Posts: 953
Joined: April 26th, 2013, 1:04 pm

Re: Belousov-Zhabotinsky sun catcher

Post by pcallahan »

This is not a suncatcher yet. Here is a 6cm 3D-print of a symmetric Belousov-Zhabotinsky pattern. It captures the intensity as a height map but does not vary in color.
20260613_165508.jpg
20260613_165508.jpg (891.37 KiB) Viewed 592 times
I could print one or maybe something larger, mold it and cast it in resin (maybe smoothed out or maybe with the ridges to see what the optical effect is like). With a little work I could probably figure out a way to mask out the three colors. I am not sure I am that ambitious.

Here is the intensity map it's based on
zbcoaster.png
zbcoaster.png (192.3 KiB) Viewed 592 times
The code hasn't changed much and you can use GIMP or similar to separate and recombine the colors.
User avatar
pcallahan
Posts: 953
Joined: April 26th, 2013, 1:04 pm

Re: Belousov-Zhabotinsky sun catcher

Post by pcallahan »

Printable for anyone interested: https://www.printables.com/model/175446 ... ative-disk

I have plans to make this more general using tiles and other runs of the pattern.
User avatar
pcallahan
Posts: 953
Joined: April 26th, 2013, 1:04 pm

Re: Belousov-Zhabotinsky sun catcher

Post by pcallahan »

I'm still working on this, but I can now set boundary conditions for 60-120 rhombus that tile both rotated and flipped. The continuity is sometimes a little off but on the whole the effect is believable. I will make some 3d-printed snap tiles when I get a chance.
image1-0.jpg
image1-0.jpg (2.07 MiB) Viewed 444 times
image1.jpg
image1.jpg (1.2 MiB) Viewed 444 times
User avatar
pcallahan
Posts: 953
Joined: April 26th, 2013, 1:04 pm

Re: Belousov-Zhabotinsky sun catcher

Post by pcallahan »

Seamless Belousov-Zhabotinsky rhombus tiles. They tile both rotated and flipped and the boundary conditions were tricky to get right. Still a work in progress but moving along. The continuity on boundaries could be better and there might be way. I've also learned a little about how these oscillations actually work over time (nothing new I'm sure) and might post something in a real CA thread if I have any interesting observations. One thing worth doing other than physical tiles is making a looping animation.
20260626_093405.jpg
20260626_093405.jpg (1.37 MiB) Viewed 297 times
20260626_093619.jpg
20260626_093619.jpg (2.42 MiB) Viewed 297 times
20260626_095553.jpg
20260626_095553.jpg (1.74 MiB) Viewed 297 times
User avatar
pcallahan
Posts: 953
Joined: April 26th, 2013, 1:04 pm

Re: Belousov-Zhabotinsky sun catcher

Post by pcallahan »

Resin cast of symmetric periodic hexagon.
20260701_063606.jpg
20260701_063606.jpg (2.87 MiB) Viewed 209 times
PLA original embedded as a coaster.
20260701_062453.jpg
20260701_062453.jpg (983.94 KiB) Viewed 209 times
Ofas1998
Posts: 1
Joined: July 8th, 2026, 11:29 pm

Re: Belousov-Zhabotinsky sun catcher

Post by Ofas1998 »

pcallahan wrote: August 1st, 2023, 4:51 pm Generated in a Python script with a hexagonal neighborhood and 120° symmetry, die-cut in two colors of acetate, and embedded in clear resin. 20230801_113853.jpg I realized after making a similar one that I could get three colored bands by cutting filters for adjacent bands and using the combination as the third color. This makes it possible to cut the filters at a higher level of detail. This is an 86mm disk and would be quite fragile otherwise and hard to remove from the cutting mat without breaking it. I made a small mistake and left islands in the red filter. I will add bridges for them when I make another. 20230731_093949.jpg Here you can see them casting a colored shadow. It does that in resin as well, but with less clarity. 20230731_093721.jpg
:D :D :D
User avatar
pcallahan
Posts: 953
Joined: April 26th, 2013, 1:04 pm

Re: Belousov-Zhabotinsky sun catcher

Post by pcallahan »

This won't be catching any sun but it's a different aesthetic. It is cast in AC730, a stone-like material, and I painted the grooves for contrast. Maybe I should make some cellular automata patterns like this. Either single generations of CGOL or rows of Rule 110.
20260711_172106.jpg
20260711_172106.jpg (3.29 MiB) Viewed 170 times
Post Reply