WTF is this?

The images you see on this blog are output from various Ulam spiral generators I built in Flash, Python and most recently using Arduino. Generally, each dot in an image represents a number with integer 1 at center. In addition to writing algorithms to test each number for primality within a set I have discovered that an infinite number of calculations can be performed to create new designs and animation algorithms. The simplicity and speed of these algorithms make them an ideal fit for embedded systems graphics, scientific, mathematical and artistic explorations.

Wednesday, June 18, 2008

The Strangest, Most Beautiful Spiral



When my spiral generator output the above image for the first time, my jaw dropped. I had previously generated some interesting spiral images using triangular and square numbers, images that others have already generated elsewhere. But I have not yet seen anything as complex or intricate as this image, at least using the Ulam spiral algorithm.

The base calculation for generating this image (using ActionScript) follows:
(Math.round(Math.sqrt(Math.pow(n,2))*(1.6180339887*3.14159265)/2)%2==0)

It's the kind of pattern that would indeed make for an excellent Persian rug design, where your eye gets lost trying to follow the paths through the maze.

The following image uses the same calculation to determine the color of the dot, but rather than starting at the center here we are starting at top left 0,0 and moving across _x, then down and repeating until the space is filled.


Now we can see that the pattern is incredibly simple. If we say gray dots are 0 and red dots are 1, then we get:
0101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000010101010101010101010101000000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000000000000000000000000000101010101010101010101010000000000000000000000000000000000001010101010101010101010100000000000000

The groups of zeros alternate between 36 zeros and 38 zeros. In between these alternations is a string of zeros and ones. The first set of mixed digits is a 12-digit-long string "010101010101". After that it's always a 23-digit-long string "10101010101010101010101".

Now I'm trying to fine tune the algorithm to see if I can focus the pattern, perhaps improving it. Here is the result of using (Math.round(Math.sqrt(Math.pow(n, (Math.sqrt(2)+1) ))*2.2)%2==0)...As you can see there is not a huge difference.



Again...(Math.round(Math.sqrt(Math.pow(pInt, (Math.sqrt(2)+1) ))*2.3)%2==0). It seems the general characteristic of the pattern is similar, yet if you study it the differences become gradually more apparent. The way the spiral patterns are visually iterating reminds me a little bit of M.C. Escher's fish transforming into birds and back again. [See Metamorphosis]


After mucking about with the multiplier I have discovered that numbers greater than PI*PHI produce tinier spiral patterns to the point of turning the whole image into a seemingly random block of static. Going the other direction improves the clarity of the spiral patterns. Here is the same algorithm using 1.5 for our multiplier:


Multiplier = 1.2


Multiplier = .9


Multiplier = .2
We've crossed the threshold and the spirals are gone.


Multiplier = .005


Why do spirals form fancy daisy chains when using PI*PHI as the multiplier? Who knows? It's just how the dots line up.

I am curious as to why having PI as part of the algorithm leads to these spirals. Here is a linear matrix (L to R, T to B) using (Math.round( Math.pow(Math.sqrt(pInt)/Math.PI, 3.3) )%2==0) per dot.




Another kind of MaxiCode




Have you ever examined a package delivered by UPS and wondered what those curious looking labels containing a matrix of dots are used for? They are quite ingenious and beautiful in their own way. If you've gotten this far in this particular post you have probably noticed how you might generate your own "maxi-code" using the principles of a Ulam spiral, a left-to-right, top-to-bottom pattern, or any contained pattern. Encoding data into a pattern is a pretty simple affair. It's the encryption that is difficult. If we take the above example of converting the Ulam spiral to a series of ones and zeroes, you wind up with what could be interpreted as a set of data encoded as a binary set. But what algorithm should one use to convert these numbers back to human readable data? Or machine-readable data? Who knows! Such is the fun in creating your own patterns, meta-languages and encoding/decoding/codec algorithms.

Tuesday, June 17, 2008

Images of Phi Part II

A Ulam spiral testing each number for if(Math.round((n * Math.PI)/1.618)%9==0)



Same idea, swapping out mod 9 with mod 5:



Calculation per dot: (Math.round(Math.sqrt(Math.pow(n,2))*1.618/2)%5==0)




Calculation per dot: (Math.round(Math.sqrt(n*1.618)/2)%5==0)



Calculation per dot: (Math.round(Math.sqrt(n*1.618))%5==0)





Calculation per dot: (Math.round(Math.sqrt(n*2))%5==0)




Here are the selected primes up to 13693 from the previous image.

Prime Numbers Ending in 1

A Ulam spiral with only primes ending with the integer 1. We start off 1, 11, 31, 41, 61, 71, 101, 131, 151.....10,331!


This prime goes to 11. Here we have all primes ending with the digits 11 from 11 to 12011.

Primes Numbers Beginning With 7

This is a Ulam spiral showing just the primes that begin with 7 (except for the yellow integer 1 at center). So, we have 7, 71, 73, 79 in the center group. The middle ring contains 701, 709, 719, 727, 733, 739, 743, 751, 757, 751, 761, 769, 773, 787, and 797. The outer ring contains 7151, 7159, 7193.... The reason we have squares appearing is fairly obvious. What I find interesting is the distribution of primes within each level. There are notable gaps in the outermost ring. Of course, that ring contains a few thousand numbers so the distribution could appear however we decide to fire off the spiral.



Same idea, this time primes beginning with 2. Notice the deficit of primes in the lower edge of the outer ring.

Sunday, June 15, 2008

Corner Primes


Primes on "corners" are connected with a line. A corner, in the case of a Ulam Spiral, is like corners in real life. It's where we turn to go in a different direction. The corner primes in this image are:

2,3,5,7,13,17,31,37,43,73,101,157,197,211,241,257,307,401,421,463,577,601,677,757,1123,1297, and 1483.


Now if you take the average of these numbers you get 242.074074074.... Subtract 1 because I said so, and you get 241.074074074..., which rounds to 241. Prime!


Do the same with 2,3,5,7,13,17. Averages to 7.8 - 1 = 6.8. Rounds to 7. Bingo. Prime!


Do it with 2,3,5,7,13,17, and 31. Averages to 11.142857. Don't subtract the 1 because then our rounded average would not be prime. Dang it.

Weird? Yes. Significant? Nope.

Saturday, June 14, 2008

Connect the Prime Dots


Here's the basic algorithm: Starting with 1, cycle through all numbers and test each for prime. If the number is prime, connect a line from the last prime number to the current prime number. The particular map stops at 337.

Zooming out to prime #14033, I give you this:


Primes Overlapping Fractals on a Ulam Spiral

Here is a typical Ulam spiral. Each bright dot is a prime number.



And here is our "rug" with the lovely Celtic pattern generated by multiplying the golden mean with PI. Where do the primes fall upon this pattern?



Overlapped primes:
As you can see, it's a complete mess. Some of the primes fit into the pattern, some don't, where the primes sit in the negative space. Nothing significant is happening here.



Or is there? Take a look at this:
The primes tend to "favor" areas where the celtic pattern's positive space occupies. That is, the negative space of the pattern, the dark regions, by and large are not polluted with primes. Of course you will find exceptions and even a contradiction: There are plenty of positive space regions (masses of red dots) where the primes also avoid. Another way to say this is the primes favor the edges, and if we continue to draw this pattern outward we may gain resolution into the nature of this happy random accident.

Alien Signals


if(Math.round(Math.sqrt(Math.pow(n,2))*(1.6180339887*3.14159265)/2)%5==0){//paint a dot}. I'm not sure what the significance is of multiplying PI with the Golden Mean. But it sure looks cool.

A little more number crunching: if(Math.round(Math.sqrt(Math.pow(pInt, (Math.sqrt(2)+1) ))*(1.6180339887*3.14159265)/2)%2==0){//paint weird pattern}


Tighten up the resolution and you approach a nice pattern for a wool rug.

Note that the picture gets clearer the farther from center you go. It seems there is simply more mathematical "space" for the pattern to be expressed.





Sin mod n, Square roots and PI



Calculation: if(Math.round(Math.sin(n))%6==0){//paint it!} As it turns out, it doesn't need to be 6 to generate this pattern because we round the SIN calculation first. So, if(Math.round(Math.sin(pInt)*Math.PI)%3==0){...} generates this:









And then there's this...




if(Math.round(Math.sqrt(pInt)*3.14159265)%2==0){//draw Tempest!}


Same formula as above but showing only the prime numbers.



And again with the primes blurred to enhance the pattern they create.



Same stuff, modding 3 this time:



Modulo 4:



Let's take the average of PI and the Golden Ratio and mod that by 2...Holy guacamole!



So if you were looking for a visual representation of what the relationship amongst primes and PI and PHI might look like, look no further.


Calculation per dot: (Math.round(Math.sqrt(Math.pow(pInt,2))*(1.6180339887*3.14159265)/2)%5==0)


Silver Ratio



Here we go round and round Ulam's spiral, testing each number not for primality, but if(Math.round(n/1+1.41421)*n%5==0), paint circle. Basically another twisted formatter using 1+√2 modulo 5. Why 5? Why not?


Strange things happen around this number: Square root of 2



Same calc, swapping in modulo 7. Looks a bit like a cousin to the n mod 7 image.




Go modulo 8:




Calculation per dot: (Math.round(pInt/(Math.sqrt(2)+1))%5==0)

Images of Phi Part I

if(Math.round(n/1.6180339887)*n%2==0){//paint the dot a color

Behold:






if(Math.round(n/1.6180339887)*n%2==0){//paint the dot a color}

Another good pattern for a rug.


Friday, June 13, 2008

3.14159265



This is a fairly strange calculation, but here goes:


if( Math.round( n /)*n%2==0 ) {//color the dot}


A lot of fractal-like features with this formula. Here's another using the same calculation but using mod 3.



Using 5 as the modulo divisor delivers strange results. My favorite of the lot:



How about a nice, modern looking rug?



Calculation per dot: Math.round(Math.sqrt(pInt)*Math.PI)%5==0


Calculation per dot: Math.round(pInt*Math.PI)%5==0




Calculation per dot: Math.round(((Math.pow(pInt, 2))*Math.PI) * (Math.sqrt(2)+1))%5==0. Some of the patterns in here look like hiragana. If you look closely you can also find Kilroy. And no, I didn't put him in there.