
Hello! I’m Peter!
Blog
-
JMM Exhibition of Mathematical Art
I was going through some old saved tweets during my move to Bluesky, and my favorite tweets to come across were those that mean something different to me know than they did when I saved them. In particular, this tweet from 2021 shows that 2021 JMM Exhibition of Mathematical Art catalog, and little did I know that just three years later, I’d be making art and finding my own pieces in the 2024 and 2025 versions.
I recreated Dan Bach’s photo with the catalogs from the Exhibitions that I took part in.
The 2024 Catalog The 2025 Catalog JMM 2024
You can read about my piece in the 2024 exhibition on my post “Triangle Center Patterns“:
Here’s the video, which really ought to be viewed in 4K!
And you can read more about the piece on the Bridges website for the 2024 exhibition.
JMM 2025
My friend and former colleague Francis Su kindly posted about my 2025 piece when he saw it at JMM:
I made some projections of this shape in Mathematica in order to plot on my AxiDrawV3 pen plotter.
You can read more about this piece on the Bridges website for the 2025 exhibition.
-
Vowel cascades
I saw a post on Bluesky that proposed a problem that I had been thinking about for a long time!
I figured that with the help of dictionary and a Python script, I could find the desired examples.
One vowel
- A: t_lk
- E: wh_n
- I: w_th
- O: fr_m
- U: cl_b
Two vowels
- AE: sm_ll
- AI: th_nks
- AO: d_wn
- AU: b_nk
- EI: m_nd
- EO: kn_w
- EU: j_st
- IO: sh_rt
- IU: sk_lls
- OU: sp_rt
Three vowels
- AEI: w_ll
- AEO: l_ss
- AEU: fl_sh
- AIO: t_p
- AIU: st_ff
- AOU: c_ts
- EIO: m_ld
- EIU: d_sk
- EOU: c_lts
- IOU: p_lls
Four vowels
- AEIO: r_d
- AEIU: b_ll
- AEOU: l_gs
- AIOU: m_st
- EIOU: d_ll
- AEIOU: b_t
Python code
Here’s my quick Python script to help find these. The dictionary has some words that I’m not familiar with (e.g. “cen,” “wir,” etc.) so I had to manually audit the results.
from wordfreq import top_n_list import re from collections import defaultdict common_words = top_n_list('en', 50000) def vowels(word): return re.findall(r'[aeiouy]', word, re.IGNORECASE) def has_one_vowel(word): return len(vowels(word)) == 1 def first_vowel(word): return vowels(word)[0] def replace_vowels(word): return re.sub(r'[aeiouyAEIOUY]', '_', word) one_vowel_words = filter(has_one_vowel, common_words) dict = defaultdict(list) for w in one_vowel_words: dict[replace_vowels(w)] = sorted(dict[replace_vowels(w)] + [first_vowel(w)]) vowel_subsets = [['a'], ['e'], ['i'], ['o'], ['u'], ['a', 'e'], ['a', 'i'], ['a', 'o'], ['a', 'u'], ['e', 'i'], ['e', 'o'], ['e', 'u'], ['i', 'o'], ['i', 'u'], ['o', 'u'], ['a', 'e', 'i'], ['a', 'e', 'o'], ['a', 'e', 'u'], ['a', 'i', 'o'], ['a', 'i', 'u'], ['a', 'o', 'u'], ['e', 'i', 'o'], ['e', 'i', 'u'], ['e', 'o', 'u'], ['i', 'o', 'u'], ['a', 'e', 'i', 'o'], ['a', 'e', 'i', 'u'], ['a', 'e', 'o', 'u'], ['a', 'i', 'o', 'u'], ['e', 'i', 'o', 'u'], ['a', 'e', 'i', 'o', 'u']] for vs in vowel_subsets: print("".join(vs).upper() + ":", ", ".join([k for k, v in dict.items() if v == vs][0:10]))
-
Cube fractals
Robert Fathauer’s fractal
On May 16th, 2024, Robert Fathauer tweeted a wonderful timelapse video of building a white cube fractal, which you can see below.
When I tried to learn more about this fractal, I found a Mathematica demo called “Shifting Cube Fractal”. I couldn’t get the demo to work quite properly, so I illustrated it myself by writing a Mathematica script to make this video:
Bluesky #MathArtMarch
In March 2025, @ayliean.bsky.social started #MathArtMarch with a list of prompts to use to make new art or post existing art. On Day 12, I saw @curved-ruler.bsky.social‘s cube fractal, and inspired it, Ayliean’s prompt, and Robert Fathauer’s timelapse, I modified the above video to show off some new perspectives.
This video has four frames where the sides of the cube are perfectly transparent, and these look very reminiscent of @curved-ruler.bsky.social‘s cube fractal.
Mathematica code
Here’s my quick and dirty Mathematica code used to make the first illustration. If you modify it, show me what you make on Bluesky! (@peterkagey.com)
nextGen[cube_, t_] := (
s = Volume[cube]^(1/3)/2;
c = RegionCentroid[cube];
{
Cube[c + s {1.5, -0.5 + t, -0.5 + t}, s],
Cube[c + s {-1/2 + t, 1.5, -1/2 + t}, s],
Cube[c + s {-0.5 + t, -0.5 + t, 1.5}, s]
}
)
frames = Table[
cubes = {{Cube[]}};
cubes =
Append[cubes,
Flatten[nextGen[#, (Sin[2 \[Pi] t + \[Pi]/4] + 1)/2] & /@
cubes[[-1]]]];
cubes =
Append[cubes,
Flatten[nextGen[#, (Sin[2 \[Pi] t + \[Pi]/4] + 1)/2] & /@
cubes[[-1]]]];
cubes =
Append[cubes,
Flatten[nextGen[#, (Sin[2 \[Pi] t + \[Pi]/4] + 1)/2] & /@
cubes[[-1]]]];
cubes =
Append[cubes,
Flatten[nextGen[#, (Sin[2 \[Pi] t + \[Pi]/4] + 1)/2] & /@
cubes[[-1]]]];
Graphics3D[
Transpose[{Table[
Hue[(3 n)/5 + (Sin[2 \[Pi]*t] + 1)/10], {n, 1, 5}], cubes}],
ViewVector ->
100*{Sin[4 \[Pi]*t - \[Pi]/4], Sin[4 \[Pi]*t - \[Pi]/4],
Sqrt[2] Cos[4 \[Pi]*t - \[Pi]/4]},
ViewVertical -> -{Sin[4 \[Pi]*t + \[Pi]/4],
Sin[4 \[Pi]*t + \[Pi]/4], Sqrt[2] Cos[4 \[Pi]*t + \[Pi]/4]},
ViewAngle -> 0.025,
ImageSize -> {720, 720}, Boxed -> False, Lighting -> "Neutral",
SphericalRegion -> True],
{t, 1/200, 1, 1/200}
]
Export["frame_000.png", frames, "VideoFrames"]