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.

Tuesday, October 21, 2008

Old Ulam spirals yield new discovery

Hidden information within 2D patterns?


The following pattern yields yet another familiar pattern when each pixel is elevated according to its derived value. Behold:

Base pattern generated with round(sqrt(pow(n, 2.71828 ))*2.71828)%2==0:




The same algorithm, but pixels are elevated along the Y axis according to the spiral counter's distilled value (e.g. 14 = 5, 11 = 2). This technique governs all numbers, no matter how large to be boiled down to no more than 9 units.


Now, the image is slightly tilted to reveal the depth we added above. Note those nested "U" shapes.


We injected new information into this pattern by taking a 2D image and making it 3D by imparting elevation to each pixel. Now let's see if these "U" shapes persist when other pattern algorithms are applied...

round(n/2.71828)*n%2==0


Secondary pattern emerges from tilted image:


So, is there hidden information with the 2D patterns here? The answer, of course (alas, hindsight), is no. We added the information to the pattern when we made it 3D.

See e - Mathematical Constant Mapped on a Ulam Spiral for the Flash-based images created from the algorithms above.

1 comment:

sphinx said...

Heyo - those patterns are orbits. They result from the periodic cycle of square root residuals.

Here I’ve listed the first 16 square roots, and then again but trimmed down to reveal the pattern. See the way the progressions in the residual (the stuff after the decimal point) show orderly growth?

1. 1
2. 1.414213562373095
3. 1.732050807568877
4. 2
5. 2.23606797749979
6. 2.449489742783178
7. 2.645751311064591
8. 2.82842712474619
9. 3
10. 3.162277660168379
11. 3.3166247903554
12. 3.464101615137755
13. 3.605551275463989
14. 3.741657386773941
15. 3.872983346207417
16. 4

1. 0
2. .4
3. .7
4. 0
5. .2
6. .4
7. .6
8. .8
9. 0
10. .1
11. .3
12. .4
13. .6
14. .7
15. .8
16. 0

Using this you can construct a function that maps any XY coordinate to number N in the Ulam Spiral, and also the function to inverse this by taking in N and returning XY.

float ulam_spiral(vec2 p)
{
float x = abs(p.x);
float y = abs(p.y);
bool q = x > y;

x = q ? x : y;
y = q ? p.x + p.y : p.x - p.y;
y = abs(y) + 4. * x * x + 1.;
x *= 2.;

return q
? (p.x > 0. ? y - x - x : y)
: (p.y > 0. ? y - x : y + x);
}


vec2 inverse_ulam(float u)
{
float r = sqrt(u);
float m = mod(r, 1.);
float p = mod(r * .5, 1.) > .5 ? 1. : -1.;
float s = p * 1.5 - m * p * 2.;
float x = m < .5 ? r * .5 * p : r * s;
float y = m > .5 ? r * .5 * p : r * p - r * s;

return vec2(x, y);
}

Note, these functions actually accept values from a higher resolution grid (decimal values are okay input,) and thus for a display that matches the original layout the result must be floored.

http://glslsandbox.com/e#48892.1

(Side note, this function requires sqrt() and thus is limited in its precision - you’ll see different results on desktop vs phone; this can be worked around, but I didn’t bother yet.)

Viewing the floating point output (before it is floored) shows the same spiral pattern. If you’re curious to hear more lemme know. : )