The Hex Crystals

To coin a phrase: Never Mind the Bollocks — Here’s the Hex Crystals! And what is a hex crystal? It’s what I call a shape that’s created algorithmo inside a hexagon and looks like a crystal:

A hex crystal


Here are some more hex-crystals:




I came across hex-crystals when I was looking at an interesting little geometrical question. How does sum(vd), the sum of distances to the vertices of a square, vary from different points, (x,y), inside the square? Say the square is created inside a circle of radius = 500 units and centered on (x,y) = (0,0). When the point is at (0,0), the center of the square, sum(vd) is obviously 2000, because the four vertices all fall on the perimeter of the circle at 500 units from the center and 4 * 500 = 2000:
0

sum(vd) = 2000 = sum of distances to vertices from (0,0)


When is sum(vd) at a maximum? When the point is on one or another of the vertices, which are at (+/-354,+/-354) units in relation to the center at (0,0):

sum(vd) = 2414 = sum of distances to vertices from (354,-354)


More precisely, the sum is 2414.213562373… = 1000 * (√2 + 1) units and the vertices are at (+/-353.55339…, +/-353.55339…) units, as simple geometry dictates for a square inside a circle of radius 500. Accordingly, sum(vd) varies between exactly 2000 and 2414.213562373… as the point moves inside the square:

sum(vd) = 2165 from (132,256)


sum(vd) = 2182 from (-135,271)


sum(vd) = 2069 from (177,51)


I wondered what shapes appeared as one traced the route of a point jumping, say, 1/2 towards the vertices according to tests on sum(vd). For example, if the point starts at (0,0) at time t0) and sum(vd) at time ti has to be alternately greater and less than sum(vd) at ti-1 for successive jumps, you get this shape:

jump = 1/2, test = sum(vd,ti) >,< sum(vd,ti-1)


You can use the binary number 10bin to represent the test on sum(vd) at ti-1 and ti-1, i.e. the test at jump 1 is sum(vd,ti) > sum(vd,ti-1), at step 2 is sum(vd,ti) < sum(vd,ti-1), and so on. Using the same test and a jump of 1/3, you get this shape:

jump = 1/3, test = sum(vd,ti,10bin)


Now the shape is clearly a fractal. So are some of the other shapes I found by applying the same kind of tests to a point jumping inside a pentagon:

vertex = 5, jump = 55/144 = fib(10) / fib(12), test on sum(vd) = 10bin


v = 5, j = 55/144, test = 10010bin


v = 5, j = 55/144, test = 11000bin


When test = 10010bin, you read the binary number left-to-right and check for s1><s0,s2<s1,s3<s2,s4>s3,s5<s4. Then you apply the same tests to subsequent jumps, i.e., you return to the beginning of the binary number and read it left-to-right again. Now let’s apply similar tests to hexagons and create some hex-crystals:

v = 6, j = 1/2, test = 10bin


Various hex-crystals (animated gif courtesy EZgif)


I searched an array to calculate the possible routes, so the same test yielded different results depending on dp, the depth of the search. This is because tl, the length of the test, fits more or less well into dp by dp modulo tl, that is, by whether tl is a factor of dp. For example, when the test is 110 and tl = 3, you get this with dp = 9:

v = 6, j = 1/2, test = 110, dp = 9


And you get this when dp = 10 (i.e., dp = 9+1):

v = 6, j = 1/2, test = 110bin, dp = 10dec


Here are some more hex-crystals:

test = 1100bin


test = 1110bin


test = 10010bin


test = 11010bin


test = 11100bin


test = 101000, dp = 12


test = 101100bin


test = 111100bin


test = 111100, dp = 11


test = 1110010bin


test = 1111100bin


test = 10010110bin


test = 10011110bin


test = 11000110bin


test = 11001110bin


test = 11010110bin


test = 11100110bin


test = 11101000bin


test = 11110010bin


test = 100101000bin


test = 100111110bin


test = 110011110bin


test = 110111000bin


test = 1001101010bin


test = 1001111000bin


test = 1001111010bin


test = 1010011110bin


test = 1011101110bin


test = 1101010000bin


test = 1110001110bin


test = 1110101000bin


test = 1110101010bin


test = 1111100010bin


j = 1/3, test = 1 (i.e., for all jumps sum(vd) at ti > sum(vd) at ti-1, center point


j = 2/3, test = 11100bin


j = 2/5, test = 10010bin


Finally, here are some hex-crystals based on a test of sorted distances from (x,y), i.e. how the vertices rank by distance from (x,y):




Worms in Terms of Perms

If you go back far enough, we’re all worms. All us animals, that is. But in a subtler sense, all life is vermiform — animals, plants, fungi, bacteria. DNA is a kind of worm, a string of chemicals encoding the recipe for an animal, plant, fungus or bacterium. And the worms of DNA can be turned into numbers, just as some numbers can be turned into worms:

3/7 = 0·0.428571428571428571428571…
154/183 = 0.841530054644808743169398907…
√2 = 1.414213562373095048801688…
π = 3.1415926535897932384626433…

Those are decimals, but there’s another kind of worm for such numbers. It’s called a continued fraction:

contfrac(3/7) = [0,2,3]
contfrac(154/183) = [0,1,5,3,4,2]
contfrac(√2) = [1,2,2,2,2,2…]
contfrac(π) = [3, 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, 1, 84, 2, 1, 1, 15…]

Extracting and enacting continued fractions is very simple. Here’s the extracting:

3/7 → 1/(3/7) = 7/3 = 2+1/3 – 2 = 1/3 → 1(1/3) = 3, ∴ contfrac(3/7) = [0,2,3]
154/183 → 1/(154/183) = 183/154 = 1 + 29/154 – 1 = 29/154 → 1/(29/154) = 154/29 = 5 + 9/29 – 5 = 9/29 → 1/(9/29) = 29/9 = 3 + 2/9 – 3 = 2/9 → 1/(2/9) = 9/2 = 4 + 1/2 – 4 = 1/2 → 1/(1/2) = 2 – 2 = 0, ∴ contfrac(154/183) = [0,1,5,3,4,2]

And here’s the enacting:

[0,2,3] → 3 → 1/3 → 1/3 + 2 = 7/3 → 1/(7/3) = 3/7
[0,1,5,3,4,2] → 2 → 1/2 → 1/2 + 4 = 9/2 → 2/9 + 3 = 29/9 → 9/29 + 5 = 154/29 → 29/154 + 1 = 183/154 → 1/(183/154) = 154/183

Once you’ve got the worm of a continued fraction, you can perm the worm, as it were, generating different fractions like this (I’m dropping the initial [0,…] of the contfracs):

[2,3,4] = contfrac(13/30)
[2,4,3] → 13/29
[3,2,4] → 09/31
[3,4,2] → 09/29
[4,2,3] → 07/31
[4,3,2] → 07/30

Reversing a continued fraction is a kind of permutation, so the fractal below represents one kind of worms in terms of perms:

Variant of a limestone fractal or gryke fractal


I call that graph a fract-L, because it’s shaped like an L and the x axis represents the simplified fractions 1/2, 1/3, 2/3, 1/4, 3/4, 1/5, 2/5, 3/5…, while the y axis represents the fractions you get by reversing the continued fractions of 1/2, 1/3, 2/3…:

contfrac(1/2) = [2] → 1/2
contfrac(1/3) = [3] → 1/3
contfrac(2/3) = [1,2] → 1/3
contfrac(1/4) = [4] → 1/4
contfrac(3/4) = [1,3] → 1/4
contfrac(1/5) = [5] → 1/5
contfrac(2/5) = [2,2] → 2/5
contfrac(3/5) = [1,1,2] → 2/5
contfrac(4/5) = [1,4] → 1/5
contfrac(1/6) = [6] → 1/6
contfrac(5/6) = [1,5] → 1/6
contfrac(1/7) = [7] → 1/7
contfrac(2/7) = [3,2] → 3/7
contfrac(3/7) = [2,3] → 2/7
contfrac(4/7) = [1,1,3] → 2/7
contfrac(5/7) = [1,2,2] → 3/7
contfrac(6/7) = [1,6] → 1/7
contfrac(1/8) = [8] → 1/8
contfrac(3/8) = [2,1,2] → 3/8
contfrac(5/8) = [1,1,1,2] → 3/8
contfrac(7/8) = [1,7] → 1/8
contfrac(1/9) = [9] → 1/9
contfrac(2/9) = [4,2] → 4/9
contfrac(4/9) = [2,4] → 2/9
contfrac(5/9) = [1,1,4] → 2/9
contfrac(7/9) = [1,3,2] → 4/9
contfrac(8/9) = [1,8] → 1/9
[…]

If you perm the worm in other ways, you get other shapes on the fract-L. I looked at continued fractions of fixed length, 4, 5 and 6, and permed them using one of the permutations of [1,2,3,4], [1,2,3,4,5] and [1,2,3,4,5,6]. Here’s a graph for fractions, a/b, and permed fractions, perm(a/b), where length(contfrac(a/b)) = 4:

x = a/b when length(contfrac(a/b)) = 4, y = fraction from contfrac(a/b) permed with [1,3,2,4]


The x axis represents simplified fractions, a/b, when len(cf(a/b)) = 4. The y axis represents the fractions found by applying the perm [1,3,2,4] to contfrac(a/b). That is, the first number of the contfrac stays where it is, the third number moves to position 2, the second number moves to position 3 and the fourth number stays where it is. In short, you simply swap the middle two numbers of contfrac(a/b). Here’s an example:

contfrac(9/43) = [4,1,3,2] → [4,3,1,2] → 11/47, because contfrac(11/47) = [4,3,1,2]

Here are more fract-Ls representing worms in terms of perms:

fract-L for contfrac(a/b) permed by [2,1,3,4]


fract-L for contfrac(a/b) permed by [3,2,1,4]


fract-L for contfrac(a/b) permed by [1,4,2,3,5] (i.e. a/b where len(contfrac(a/b)) = 5)


fract-L for contfrac(a/b) permed by [1,5,3,4,2]


fract-L for contfrac(a/b) permed by [2,1,4,3,5]


fract-L for contfrac(a/b) permed by [3,4,1,2,5]


fract-L for contfrac(a/b) permed by [4,2,3,1,5]


fract-L for contfrac(a/b) permed by [4,2,5,3,1]


fract-L for contfrac(a/b) permed by [4,3,2,1,5]


fract-L for contfrac(a/b) permed by [5,3,4,2,1]


fract-L for contfrac(a/b) permed by [2,1,4,3,5,6] (i.e. a/b where len(contfrac(a/b)) = 6)


fract-L for contfrac(a/b) permed by [2,1,5,4,3,6]


fract-L for contfrac(a/b) permed by [3,2,1,4,5,6]


fract-L for contfrac(a/b) permed by [3,2,1,5,4,6]


fract-L for contfrac(a/b) permed by [3,5,1,4,2,6]


fract-L for contfrac(a/b) permed by [4,2,5,1,3,6]


fract-L for contfrac(a/b) permed by [4,3,2,1,5,6]


fract-L for contfrac(a/b) permed by [4,5,2,3,1,6]


fract-L for contfrac(a/b) permed by [1,3,2,6,5,4,7] (i.e. a/b where len(contfrac(a/b)) = 7)


fract-L for contfrac(a/b) permed by [1,5,2,6,3,4,7]


fract-L for contfrac(a/b) permed by [5,6,3,7,4,1,2]


fract-L for contfrac(a/b) permed by [6,2,3,5,4,1,7]


fract-L for contfrac(a/b) permed by [6,2,5,4,7,3,1]


Post-Performative Post-Scriptum

Much as I hate the phrase “in terms of”, I was happy to use it in the title of this post. After all, it isn’t ugly but assonant there. And it began life in mathematics, where it still has its proper meaning rather than being pretentious and prolix:

How did this complex preposition come into being? The OED [Oxford English Dictionary] reveals that it has been in use since the mid-18c. as a mathematical expression “said of a series…stated in terms involving some particular (my emphasis) quantity”, and illustrates this technical usage by citing examples from the work of Herbert Spencer (1862), J. F. W. Herschel (1866), and other writers. From this technical use came at first a trickle and, after the 1940s, a flood of imitative uses by non-mathematicians. — “Terminal Trinity


Elsewhere Other-Engageable

A Fracteasel on a Fract-L — an earlier look at continued fractions and fractal fract-Ls

A FracTeasel on a Fract-L

Here are two new fractals, both of which remind me of the seedheads of the wildflower known as a teasel, Dipsacus fullonum:

A FracTeasel fractal


Dried seedheads of teasel, Dipsacus fullonum (Wikipedia)


Another FracTeasel fractal (embedded in the first)


Flowering seedhead of teasel, Dipsacus fullonum (Wikipedia)


How do you create the two FracTeasels? Let’s look first at the fractal they’re inspired by. In “Back to Frac’” I talked about this fractional fractal, a variant of what I call the limestone fractal:

Variant of a limestone fractal or gryke fractal


It’s a fractal on a fract-L, that is, the x and y co-ordinates of the red L represent pairs of fractions generating decimals between 0 and 1. The x represents the fractions a1/b1 = 1/n to (n-1)/n in simplest form: 1/2, 1/3, 2/3, 1/4, 3/4, 1/5, 2/5, 3/5, 4/5, 1/6, 5/6, 1/7, 2/7, 3/7, 4/7, 5/7, 6/7, 1/8, 3/8, 5/8, 7/8,…

And what about the y? It represents the fraction found by taking the continued fraction of a1/b1, reversing it, and generating a new fraction, a2/b2, from the reversal. For example, here’s the continued fraction of a1/b1 = 3/23 = 0.1304347826…:

contfrac(3/23) = 7,1,2

The continued fraction of a1/b1 = 3/23 is used like this to reconstruct a1/b1:

7,1,2

0 → 1 / (0 + 2) = 1/2 → 1 / (1/2 + 1) = 2/3 → 1 / (7 + 2/3) = 3/23

Now reverse the continued fraction, 7,1,2 → 2,1,7, and generate a2/b2:

2,1,7

0 → 1 / (0 + 7) = 1/7 → 1 / (1/7 + 1) = 7/8 → 1 / (2 + 7/8) = 8/23 = 0.3478260869565…

The limestone fractal above appears when a1/b1 → a2/b2 for a1/b1 = 1/2, 1/3, 2/3, 1/4, 3/4, 1/5, 2/5, 3/5, 4/5, 1/6, 5/6, 1/7, 2/7, 3/7, 4/7, 5/7, 6/7, 1/8, 3/8, 5/8, 7/8,… But you can do other things to contfrac(a1/b1) beside just reversing it. What about the permutations of contfrac(a1/b1), for example? If length(contfrac(a1/b1)) = n, the permutations can generate up to n! (factorial n) new a2/b2 for the y co-ordinate (if all the numbers of contfrac(a1/b1) are different, you’ll get n! permutations). The resultant fractal is the first of the FracTeasels above (note that a2/b2 isn’t multiplied by two):

FracTeasel #1 from fract-L for y = perm(contfrac(a1/b1))


If you think about it, you’ll see that the fractal from permed contfrac(a1/b1) contains the fractal from reversed contfrac(a1/b1). It also contains the second FracTeasel:

FracTeasel #2


How so? Because the second FracTeasel — let’s call it the stemmed FracTeasel — is created by shifting some numbers in contfrac(a1/b1) and leaving others alone. For example:

contfrac(940/1089) = 1, 6, 3, 4, 5, 2 → 1, 4, 3, 2, 5, 6 = contfrac(1008/1243)

So the function is finding one particular permutation of contfrac(a1/b1) to generate a2/b2, not all permutations. And so the function creates the stemmed FracTeasel, which carries an infinite number of seedheads on the same stem. To show that, here’s an animated gif zooming in on the bend of the fract-L for the stemmed FracTeasel:

Zooming the FracTeasel (animated at ezGif)


Elsewhere Other-Accessible…

I Like Gryke — a first look at the limestone fractal
Lime Time — more on the limestone fractal

Back to Frac’

Here’s a second serendipitous fractal:

A serendipitous fractal on a fract-L


It looks like (and is related to) the limestone fractal and I found it similarly serendipitously. This time I was looking at continued fractions, a simple yet subtle and seductive way of representing non-integer numbers like 2/3 and 7/9 (or √2 and π). To generate a continued fraction from a/b < 1, you divide a/b into 1 and take away the integer part. Then you repeat with the remainder until nothing is left (or, as with irrationals like 1/√2 and 1/π, you've calculated long enough for your needs). The integers at each stage are the numbers of the continued fraction. Here is the working for contfrac(2/3), the continued fraction of 2/3:

int(1/(2/3)) = int(3/2) = int(1.5) = 1
3/2 – 1 = 1/2
int(1/(1/2)) = int(2) = 2
2 – 2 = 0

contfrac(2/3) = 1, 2

By working backwards with (1, 2), you can use the continued fraction to reconstruct the original number a/b. Start with a/b = 0/1:

1 / (0/1 + 2) = 1 / ((0+2*1)/2) = 1 / (2/1) = 1/2
1 / (1/2 + 1) = 1 / ((1+2*1)/2) = 1 / (3/2) = 2/3

And here’s the working for contfrac(7/9), the continued fraction of 7/9:

int(1/(7/9)) = int(9/7) = int(1.285714…) = 1
9/7 – 1 = 2/7
int(1/(2/7)) = int(7/2) = int(3.5) = 3
7/2 – 3 = 1/2
int(1/(1/2)) = int(2) = 2
2 – 2 = 0

contfrac(7/9) = 1, 3, 2

And here’s the reconstruction of 7/9 from its continued fraction, starting again with a/b = 0/1:

1 / (0/1 + 2) = 1 / ((0+2*1)/2) = 1 / (2/1) = 1/2
1 / (1/2 + 3) = 1 / ((1+2*3)/2) = 1 / (7/2) = 2/7
1 / (2/7 + 1) = 1 / ((2+7*1)/7) = 1 / (9/7) = 7/9

From that simple algorithm arise subtle and seductive things. Look at some continued fractions, cf(a/b), for a/b in simplest form (giving only the first few reciprocals, 1/b, because cf(1/b) = b). Interesting patterns appear, e.g. when a/b uses adjacent or nearly adjacent Fibonacci numbers:

cf(1/3) = 3 = cf(0.333333333…)
cf(2/3) = 1,2 = cf(0.666666666…)
cf(1/4) = 4 = cf(0.25)
cf(3/4) = 1,3 = cf(0.75)
cf(1/5) = 5 = cf(0.2)
cf(2/5) = 2,2 = cf(0.4)
cf(3/5) = 1,1,2 = cf(0.6)
cf(4/5) = 1,4 = cf(0.8)
cf(5/6) = 1,5 = cf(0.833333333…)
cf(2/7) = 3,2 = cf(0.285714285…)
cf(3/7) = 2,3 = cf(0.428571428…)
cf(4/7) = 1,1,3 = cf(0.571428571…)
cf(5/7) = 1,2,2 = cf(0.714285714…)
cf(6/7) = 1,6 = cf(0.857142857…)
cf(3/8) = 2,1,2 = cf(0.375)
cf(5/8) = 1,1,1,2 = cf(0.625)
cf(7/8) = 1,7 = cf(0.875)
cf(2/9) = 4,2 = cf(0.222222222…)
cf(4/9) = 2,4 = cf(0.444444444…)
cf(5/9) = 1,1,4 = cf(0.555555555…)
cf(7/9) = 1,3,2 = cf(0.777777777…)
cf(8/9) = 1,8 = cf(0.888888888…)
cf(3/10) = 3,3 = cf(0.3)
cf(7/10) = 1,2,3 = cf(0.7)
cf(9/10) = 1,9 = cf(0.9)
cf(2/11) = 5,2 = cf(0.181818181…)
cf(3/11) = 3,1,2 = cf(0.272727272…)
cf(4/11) = 2,1,3 = cf(0.363636363…)
cf(5/11) = 2,5 = cf(0.454545454…)
cf(6/11) = 1,1,5 = cf(0.545454545…)
cf(7/11) = 1,1,1,3 = cf(0.636363636…)
cf(8/11) = 1,2,1,2 = cf(0.727272727…)
cf(9/11) = 1,4,2 = cf(0.818181818…)
cf(10/11) = 1,10 = cf(0.909090909…)
cf(5/12) = 2,2,2 = cf(0.416666666…)
cf(7/12) = 1,1,2,2 = cf(0.583333333…)
cf(11/12) = 1,11 = cf(0.916666666…)
cf(2/13) = 6,2 = cf(0.153846153…)
cf(3/13) = 4,3 = cf(0.230769230…)
cf(4/13) = 3,4 = cf(0.307692307…)
cf(5/13) = 2,1,1,2 = cf(0.384615384…)
cf(6/13) = 2,6 = cf(0.461538461…)
cf(7/13) = 1,1,6 = cf(0.538461538…)
cf(8/13) = 1,1,1,1,2 = cf(0.615384615…)
cf(9/13) = 1,2,4 = cf(0.692307692…)
cf(10/13) = 1,3,3 = cf(0.769230769…)
cf(11/13) = 1,5,2 = cf(0.846153846…)
cf(12/13) = 1,12 = cf(0.923076923…)
cf(3/14) = 4,1,2 = cf(0.214285714…)
cf(5/14) = 2,1,4 = cf(0.357142857…)
cf(9/14) = 1,1,1,4 = cf(0.642857142…)
cf(11/14) = 1,3,1,2 = cf(0.785714285…)
cf(13/14) = 1,13 = cf(0.928571428…)
cf(2/15) = 7,2 = cf(0.133333333…)
cf(4/15) = 3,1,3 = cf(0.266666666…)
cf(7/15) = 2,7 = cf(0.466666666…)
cf(8/15) = 1,1,7 = cf(0.533333333…)
cf(11/15) = 1,2,1,3 = cf(0.733333333…)
cf(13/15) = 1,6,2 = cf(0.866666666…)
cf(14/15) = 1,14 = cf(0.933333333…)
cf(3/16) = 5,3 = cf(0.1875)
cf(5/16) = 3,5 = cf(0.3125)
cf(7/16) = 2,3,2 = cf(0.4375)

After investigating some of those patterns, I wondered what happened when you reversed the continued fraction cf(a/b) and used those reversed numbers backward (that is, used the numbers of cf(a/b) forward) to generate another and different a/b. And a/b will always be different unless cf(a/b) is a palindrome, like cf(5/12) = 2,2,2 or cf(5/13) = 2,1,1,2 or cf(4/15) = 3,1,3. Note that a continued fraction never ends in 1, so that when reversing, say, cf(5/8) = (1, 1, 1, 2), you need an adjustment from (2, 1, 1, 1) to (2, 1, 1+1) = (2, 1, 2). Here’s a little of what happens when you reverse cf(a1/b1) to generate a2/b2:

cf(1/2) = 2 → 2 = cf(1/2)
1/2 = 0.5 : 0.5 = 1/2
cf(1/3) = 3 → 3 = cf(1/3)
1/3 = 0.333333333 : 0.333333333 = 1/3
cf(2/3) = 1, 2 → 2, 1 → 3 = cf(1/3)
2/3 = 0.666666666 : 0.333333333 = 1/3
cf(3/4) = 1, 3 → 3, 1 → 4 = cf(1/4)
3/4 = 0.75 : 0.25 = 1/4
cf(2/5) = 2, 2 → 2, 2 = cf(2/5)
2/5 = 0.4 : 0.4 = 2/5
cf(3/5) = 1, 1, 2 → 2, 1, 1 → 2, 2 = cf(2/5)
3/5 = 0.6 : 0.4 = 2/5
cf(4/5) = 1, 4 → 4, 1 → 5 = cf(1/5)
4/5 = 0.8 : 0.2 = 1/5
cf(5/6) = 1, 5 → 5, 1 → 6 = cf(1/6)
5/6 = 0.833333333 : 0.166666666 = 1/6
cf(2/7) = 3, 2 → 2, 3 = cf(3/7)
2/7 = 0.285714286 : 0.428571428 = 3/7
cf(3/7) = 2, 3 → 3, 2 = cf(2/7)
3/7 = 0.428571429 : 0.285714286 = 2/7
cf(4/7) = 1, 1, 3 → 3, 1, 1 → 3, 2 = cf(2/7)
4/7 = 0.571428571 : 0.285714286 = 2/7
cf(5/7) = 1, 2, 2 → 2, 2, 1 → 2, 3 = cf(3/7)
5/7 = 0.714285714 : 0.428571429 = 3/7
cf(6/7) = 1, 6 → 6, 1 → 7 = cf(1/7)
6/7 = 0.857142857 : 0.142857143 = 1/7
cf(3/8) = 2, 1, 2 → 2, 1, 2 = cf(3/8)
0.375 : 0.375
cf(5/8) = 1, 1, 1, 2 → 2, 1, 1, 1 → 2, 1, 2 = cf(3/8)
0.625 : 0.375
cf(7/8) = 1, 7 → 7, 1 → 8 = cf(1/8)
0.875 : 0.125
cf(2/9) = 4, 2 → 2, 4 = cf(4/9)
0.222222222 : 0.444444444
cf(4/9) = 2, 4 → 4, 2 = cf(2/9)
0.444444444 : 0.222222222

And if you plot x = a1/b1 and y = (a2/b2 * 2) on a fract-L, that is, a graph whose horizontal and vertical arms represent 0 to 1, you get the fractal right at the beginning:

Fract-L for x = a1/b1 and y = (a2/b2 * 2), where a2/b2 is generated from reversed(cf(a1/b1))


You need to use (a2/b2 * 2) because a2/b2 from reversed(cf(a1/b1)) is always <= 0.5, so using raw a2/b2 generates this graph:

Fract-L for x = a1/b1 and y = a2/b2 (i.e. a2/b2 is unadjusted)


Why is it always true that a2/b2 <= 0.5? For two reasons. First, a/b > 0.5 always generate continued fractions that start with 1, like cf(2/3) = 1, 2 or cf(3/4) = 1, 3 or cf(3/5) = 1, 1, 2. Second, as previously mentioned, no continued fraction ends with 1. Therefore a reversed cf(a1/b1), where the final number, n > 1, moves to the beginning, will never begin with 1 and the a2/b2 generated from reversed(cf(a1/b1)) will always be less than 0.5 (or equal to it in the solitary case of cf(1/2) = 2).

Now let's look at the development of the fractal as a1/b1 uses larger and larger denominators:

Fract-L for x = a1/b1 and y = (a2/b2 * 2) for a1/b1 <= 6/7


Fract-L for for a1/b1 <= 14/15


Fract-L for a1/b1 <= 30/31


Fract-L for a1/b1 <= 62/63


Fract-L for a1/b1 <= 126/127


Fract-L for a1/b1 <= 254/255


Fract-L for a1/b1 <= 357/358


Fract-L for a1/b1 <= 467/468


Animated fract-L for x = a1/b1 and y = (a2/b2 * 2) (animated at ezGif)


The fractal changes subtly when you restrict the b1 of a1/b1 in some way, say using multiples of 2, 3, 4, 5…:

Fract-L for x = a1/b1 and y = (a2/b2 * 2) for b1 = n = 2, 3, 4, 5, 6, 7, 8…


Fract-L for b1 = 2n = 2, 4, 6, 8, 10…


Fract-L for b1 = 3n = 3, 6, 9, 12, 15…


Fract-L for b1 = 4n


Fract-L for b1 = 5n


Fract-L for b1 = 6n


Animated fract-L for b1 = 1n..12n (animated at ezGif)


Finally, here are fract-Ls when b1 is a triangular, square, hexagonal or octagonal number:

Fract-L for x = a1/b1 and y = (a2/b2 * 2) for triangular(b1) = 3, 6, 10, 15, 21, 28,…


Fract-L for square(b1) = 4, 9, 16, 25, 36, 49,…


Fract-L for hexagonal(b1) = 6, 15, 28, 45, 66, 91,…


Fract-L for octagonal(b1) = 8, 21, 40, 65, 96, 133,…


Elsewhere Other-Accessible…

Back to Drac’ — a parallel pun for a pre-previous fractal
I Like Gryke — a first look at the limestone fractal
Lime Time — more on the limestone fractal

Fractional Fractal Fract-Ls

This is the surpassingly special Stern-Brocot sequence:

0, 1, 1, 2, 1, 3, 2, 3, 1, 4, 3, 5, 2, 5, 3, 4, 1, 5, 4, 7, 3, 8, 5, 7, 2, 7, 5, 8, 3, 7, 4, 5, 1, 6, 5, 9, 4, 11, 7, 10, 3, 11, 8, 13, 5, 12, 7, 9, 2, 9, 7, 12, 5, 13, 8, 11, 3, 10, 7, 11, 4, 9, 5, 6, 1, 7, 6, 11, 5, 14, 9, 13, 4, 15, 11, 18, 7, 17, 10, 13, 3, 14, 11, 19, 8, 21, 13, 18, 5, 17, 12, 19, … (A002487 at the Online Encyclopedia of Integer Sequences)


And why is the sequence special? Because if you take successive pairs of the apparently arbitrarily varying numbers, you get every rational fraction in its simplest form exactly once. So 1/2, 2/3, 6/11 and 502/787 appear once and then never again. And so do 2/1, 3/2, 11/6 and 787/502. Et cetera, ad infinitum. If you map the Stern-Brocot sequence against the related Calkin-Wilk sequence, which has the same “all-simplest-fractions-exactly-once” properties, you can create this fractal, which I call a limestone fractal or gryke fractal:

Gryke fractal by mapping Stern-Brocot sequence against Calkin-Wilf sequence


The graph is what I call a Fract-L, because the lines for the x,y coordinates create an L. Each coordinate runs from 0 to 1, with the x set by the fraction from the Stern-Brocot sequence and the y set by the fraction from the Calkin-Wilf sequence (if a > b in a/b, use the conversion 1/(a/b) = b/a). But you can also find interesting patterns by mapping the Stern-Brocot sequence against itself. That is, you use two Stern-Brocot sequences that start in different places. Now, there are complicated ways to create the Stern-Brocot sequence using mathematical trees and sequential algorithms and so on. But there’s also an astonishingly simple way, a formula created by the Israeli mathematician Moshe Newman. If (a,b) is one pair of successive numbers in the sequence, the next pair (a,b) is found like this:

c = b
b = (2 * int(a/b) + 1) * b – a
a = c

This means that you can seed a Stern-Brocot sequence with any (correctly simplified) a/b and it will continue in the right way. If the two SB-sequences for x and y are both seeded with (0,1), you get this 45° line, because each successive a/b for (x,y) is identical:

Stern-Brocot pairs seeded with x ← (0,1) and y ← (0,1)


The further you extend the sequences, the less broken the 45° line will appear, because the points determined by a/b for x and y will get closer and closer together (but the line will never be solid, because any two rationals are separated by an infinity of irrationals). Now try offsetting the SB-sequences for x,y by using different seeds. Different fractal patterns appear, which all appear to be subsets (or fractions) of the limestone fractal above (see animated gif below):

Stern-Brocot pairs seeded with x ← (0,1) and y ← (1,1)


x ← (0,1) and y ← (1,2)


x ← (0,1) and y ← (1,3)


x ← (0,1) and y ← (2,3)


x ← (0,1) and y ← (3,4)


x ← (0,1) and y ← (6,7)


x ← (1,2) and y ← (1,9)


x ← (1,4) and y ← (1,6)


x ← (1,7) and y ← (1,8)


x ← (2,3) and y ← (4,5) — apparently identical to x ← (1,4) and y ← (1,6) above


x ← (26,25) and y ← (1,10)


Gryke fractal compared with Stern-Brocot-pair patterns (animated at ezGif)


And here’s what happens when the seed-fractions for x run from 1/3 to 12/13, while the seed-fraction for y is held constant at 1/23:

x ← (1,13) and y ← (1,23)


x ← (2,13) and y ← (1,23)


x ← (3,13) and y ← (1,23)


x ← (4,13) and y ← (1,23)


x ← (5,13) and y ← (1,23)


x ← (6,13) and y ← (1,23)


x ← (7,13) and y ← (1,23)


x ← (8,13) and y ← (1,23)


x ← (9,13) and y ← (1,23)


x ← (10,13) and y ← (1,23)


x ← (11,13) and y ← (1,23)


x ← (12,13) and y ← (1,23)


Animated gif for x ← (n,13) and y ← (1,23) (animated at ezGif)


Previously Pre-Posted

I Like Gryke — a first look at the limestone fractal
Lime Time — more on the fractal

Fractional Fractal

Serendipity in some simplification statistics. That’s what I encountered the other day. I was looking at the ways to simplify this set of fractions:

1/2, 1/3, 2/3, 1/4, 2/4, 3/4, 1/5, 2/5, 3/5, 4/5, 1/6, 2/6, 3/6, 4/6, 5/6, 1/7, 2/7, 3/7, 4/7, 5/7, 6/7, 1/8, 2/8, 3/8, 4/8, 5/8, 6/8, 7/8, 1/9, 2/9, 3/9, 4/9, 5/9, 6/9, 7/9, 8/9, 1/10, 2/10, 3/10, 4/10, 5/10, 6/10, 7/10, 8/10, 9/10, 1/11, 2/11, 3/11, …

The underlined fractions are not in their simplest possible form. For example, 2/4 simplifies to 1/2, 2/6 to 1/3, 3/6 to 1/2, and so on:

1/2, 1/3, 2/3, 1/4, 2/4 → 1/2, 3/4, 1/5, 2/5, 3/5, 4/5, 1/6, 2/6 → 1/3, 3/6 → 1/2, 4/6 → 2/3, 5/6, 1/7, 2/7, 3/7, 4/7, 5/7, 6/7, 1/8, 2/8 → 1/4, 3/8, 4/8 → 1/2, 5/8, 6/8 → 3/4, 7/8, 1/9, 2/9, 3/9 → 1/3, 4/9, 5/9, 6/9 → 2/3, 7/9, 8/9, 1/10, 2/10 → 1/5, 3/10, 4/10 → 2/5, 5/10 → 1/2, 6/10 → 3/5, 7/10, 8/10 → 4/5, 9/10, 1/11, 2/11, 3/11, …

I counted the number of times the simplest possible fractions occurred when simplifying all fractions a/b for (b = 2..n, a = 1..b-1), then displayed the stats as a graph running from 0/1 to 1/1. And there was serendipity in these simplification statistics, because a fractal had appeared:

Graph for count of simplest possible fractions from a/b for (b = 2..n, a = 1..b-1)


It’s interesting to work out what fractions appear where. For example, the peak in the middle is 1/2, but what are the next-highest peaks on either side? The answers are more obvious in the colored version of the graph:

Colored graph for count of simplest possible fractions
Key: n/2, n/3, n/4, n/5, n/6, n/7


The line for 1/2 is red, the lines for 1/3 and 2/3 in light green, the lines for 1/4 and 3/4 in yellow, and so on. But those graphs appear in an equilateral triangle, as it were. The fractals get easier to see in the full-sized versions of these widened graphs:

Widened graph for count of simplest possible fractions from a/b for (b = 2..n, a = 1..b-1)

(click for full size)


Widened and colored graph for count of simplest possible fractions

(click for full size)


The Wyrm Ferns

A fern is a fractal, a shape that contains copies of itself at smaller and smaller scales. That is, part of a fern looks like the fern as a whole:

Fern as fractal (source)


Millions of years after Mother Nature, man got in on the fract, as it were:

The Sierpiński triangle, a 2d fractal


The Sierpiński triangle is a fractal created in two dimensions by a point jumping halfway towards one or another of the three vertices of a triangle. And here is a fractal created in one dimension by a point jumping halfway towards one or another of the two ends of a line:

A 1d fractal


In one dimension, the fractality of the fractal isn’t obvious. But you can try draggin’ out (or dragon out) the fractality of the fractal by ferning the wyrm, as it were. Suppose that after the point jumps halfway towards one or another of the two points, it’s rotated by some angle around the midpoint of the two original points. When you do that, the fractal becomes more and more obvious. In fact, it becomes what’s called a dragon curve (in Old English, “dragon” was wyrm or worm):

Fractal with angle = 5°


Fractal 10°


Fractal 15°


Fractal 20°


Fractal 25°


Fractal 30°


Fractal 35°


Fractal 40°


Fractal 45°


Fractal 50°


Fractal 55°


Fractal 60°


Fractal 0° to 60° (animated at ezGif)


But as the angle gets bigger, an interesting aesthetic question arises. When is the ferned wyrm, the dragon curve, at its most attractive? I’d say it’s when angle ≈ 55°:

Fractal 50°


Fractal 51°


Fractal 52°


Fractal 53°


Fractal 54°


Fractal 55°


Fractal 56°


Fractal 57°


Fractal 58°


Fractal 59°


Fractal 60°


Fractal 50° to 60° (animated)


At angle >= 57°, I think the dragon curve starts to look like some species of bristleworm, which are interesting but unattractive marine worms:

A bristleworm, Nereis virens (see polychaete at Wikipedia)


Finally, here’s what the ferned wyrm looks like in black-and-white and when it’s rotating:

Fractal 0° to 60° (b&w, animated)


Fractal 56° (rotating)


Fractal 56° (b&w, rotating)


Double fractal 56° (b&w, rotating)


Previously Pre-Posted (Please Peruse)…

Curvous Energy — a first look at dragon curves
Back to Drac’ — another look at dragon curves

Squaring the Triangle

It’s an interesting little exercise in elementary trigonometry to turn the Sierpiński triangle…

A Sierpiński triangle


…into its circular equivalent:

A Sierpiński trisc


You could call that a trisc, because it’s a triangle turned into a disc. And here’s triangle-and-trisc in one image:

Sierpiński triangle + Sierpiński trisc


But what’s the square equivalent of a Sierpiński triangle? This is:

Square from Sierpiński triangle


You can do that directly, as it were:

Sierpiński triangle → square


Or you can convert the triangle into a disc, then the disc into a square, like this:

Sierpiński triangle → trisc → square


Now try converting the triangle into a pentagon:

Pentagon from Sierpiński triangle


Sierpiński triangle → pentagon


Sierpiński triangle → trisc → pentagon


And a hexagon:

Hexagon from Sierpiński triangle


Sierpiński triangle → hexagon


Sierpiński triangle → trisc → hexagon


But you can also convert the Sierpiński trisc back into a Sierpiński triangle, then into a Sierpiński trisc again:

Sierpiński triangle → trisc → triangle → trisc


Sierpiński triangle → trisc → triangle → trisc (animated at Ezgif)


Sierpiński triangle → trisc → triangle → trisc (b&w)


Sierpiński triangle → trisc → triangle → trisc (b&w) (animated at Ezgif)


After triangles come squares. Here’s a shape called a T-square fractal:

T-square fractal


And here’s the circular equivalent of a T-square fractal:

T-square fractal → T-squisc


T-square fractal + T-squisc


If a disc from a triangle is a trisc, then a disc from a square is a squisc (it would be pentisc, hexisc, heptisc for pentagonal, hexagonal and heptagonal fractals). Here’s the octagonal equivalent of a T-square fractal:

Octagon from T-square fractal


As with the Sierpiński trisc, you can use the T-squisc to create the T-octagon:

T-square fractal → T-squisc → T-octagon (color)


Or you can convert the T-square directly into the T-octagon:

T-square fractal to T-octagon fractal

But using the squisc makes for interesting multiple images:


T-square fractal → T-squisc → T-octagon (b&w)


T-square fractal → T-squisc → T-octagon → T-squisc


T-square fractal → T-squisc → T-octagon → T-squisc (animated at Ezgif)


The conversions from polygon to polygon look best when the number of sides in the higher polygon are a multiple of the number of sides in the lower, like this:

Sierpiński triangle → Sierpiński hexagon → Sierpiński nonagon


Scout the Routes

Triangles? Yes. Squares? No. If you scout the routes with a triangle, you get a beautiful fractal. If you scout the routes with a square, you don’t. Here’s what you get with a triangle:

A Sierpiński triangle


But how do you scout the routes? (That phrase works best in the American dialects where “scout” rhymes with “route”.) Simple: you mark the final positions reached when a point traces all possible ways of jumping, say, eight times 1/2-way towards the vertices of a polygon. Here’s an animation of a point scouting the routes of eight jumps towards the vertices of a triangle (it starts each time at the center):

Creating a Sierpiński triangle by scouting the routes (animated at Ezgif)


If you scout the routes with a square, you don’t get a fractal. Instead, the interior of the square fills evenly (and boringly) with the end-points of the routes:

Scouting the routes with a square (animated at Ezgif)


But you can create fractals with a square if you out routes as you scout routes. That is, if you exclude some routes and don’t mark their end-points. One way to do this is to compare the proposed next jump-vertex (vertex-jumped-towards) with the previous jump-vertex. For example, if the proposed jump-vertex, jv[t], is the same as the previous jump-vertex, jv[t-1], you don’t jump towards jv[t] or you jump towards it in a different way. The test is jv[t] = jv[t-1] + vi. If vi = 0 and you jump towards the clockwise neighbor of jv when the test is true, you get a fractal looking like this:

vi = 0, action = jv → jv + 1


Here’s the fractal if you jump towards the clockwise-neighbor-but-one when the test is true:

vi = 0, action = jv + 2


Now try varying the vi of the jv[t-1] + vi:

vi = 2, action = jv + 2


vi = 2, action = jv + 1


vi = 3, action = jv + 1


Or what about jumping in a different way towards jv when the test is true? If you jump 2/3 of the way rather 1/2, you get his fractal:

vi = 2, action = jump 2/3


And if you jump 4/3 of the way (i.e., you overshoot the vertex jv), you get this fractal:

vi = 0, action = jump 4/3rds to vertex


vi = 0, jump 4/3 (guide-square removed)


vi = 2, jump 4/3rds (guide-square removed)


And in this fractal the point jumps 2/3 of the way to the center of the square when the test is true:

vi = 2, action = jump 2/3rds of way to center of square


But why apply only one test to jv[1] and use only when one alternative jump? If jv[t] = jv[t-1] + 1 or jv[t] = jv[t-1] + 3, jv[t] becomes jv[t]+1 or jv[t]+3, respectively, you get this fractal:

vi = 1, jv + 1; vi = 3, jv + 3


Here are more fractals created by single and double tests:

vi = 1, jv + 1


vi = 0, jump 2/3


vi = 0, jump towards center 2/3rds


vi = 1, jump-center 2/3


vi = 2, jump 1/3; vi = 3, jump 1/1 (i.e, 1)


vi = 0, jv + 2; vi = 2, jump-center 1/2


vi = 0, jv + 2; vi = 2, jump-center 2/3


vi = 0, jv + 2; vi = 2, jump-center 4/3


vi = 0, jv + 1; vi = 2, jump 2/3


vi = 0, jv + 2; vi = 2, jump 2/3


vi = 0, jump 4/3; vi = 2, jv + 2


vi = 0, jump 2/3; vi = 2, jv + 1


vi = 0, jump 4/3; vi = 1, jv + 2


vi = 0, jump 2/3; vi = 2, jump 1/3


vi =0, jump 1/3; vi = 2, jump 2/3


vi = 0, jump 0/1 (i.e, 0); vi = 2, jump 1/3