Home > Graphics, Python, Strange Attractors > Strange Attractors

Strange Attractors

Lately I’ve experimented with finding strange attractors — A complex mathematical creature generated by a simple repetitive rule. To generate these images, an “x, y” point is first chosen at random and the corresponding pixel is colored white (in a simplified case). Two functions then decide the next “x, y” point:

x = f(x,y)\\ y = g(x,y)

Which just means that each new x position is determined by some formula incorporating the current x and/or y position, and each new y position is determined by some other formula incorporating the current x and/or y position. Depending on the formulae used, after many thousands of repetitions this may or may not generate an image of a strange attractor.

So it seems that the trick to finding these strange attractors is to simply try out  many formulae hoping to generate some interesting patterns. So what formula should I use? According to ThinkQuest, the most common attractor is the quadratic attractor. The formulae used for a quadratic attractor take the general form:

new\enspace x=ax^2+bxy+cy^2+dx+ey+f

To generate infinite equations of that form I need only tweak the coefficients a, b, c, d, e and f. I can leave out any of the terms (ie. the coefficient can be 0,) or I can leave in a term with no coefficient (ie. a coefficient of 1 is allowed.) For example if I decide on the coefficients 1.4, 0, 1, 2, 1 and -1.2 then the equation will look like:

new\enspace x=1.4x^2+y^2+2x+y-1.2

I put together a Python class to generate these equations:

class Formula(object):
    def __init__(self):
        # generate the random coefficients
        self.coefficients = [random.choice([random.random()*4-2,
                        1])for x in range(6)]

    def __call__(self, x, y):
        a, b, c, d, e, f = tuple(self.coefficients)
        return a*(x**2) + b*x*y + c*(y**2) + d*x + e*y + f

This class generates Formula objects which can be called as if they were functions. An example usage would be:

f = Formula()
g = Formula()
newx = f(oldx, oldy)
newy = g(oldx, oldy)

This first attempt is naïve in places but it succeeded in generating the first real results:

Not bad for a first attempt I think. Full Python source follows:

import Image
import random
from math import floor

SIZE = 200 # image size

img_index = 0

class Formula(object):
    def __init__(self):
        self.coefficients = [random.choice([random.random()*4-2,
                        1])for x in range(6)]
        #print self.coefficients

    def __call__(self, x, y):
        a, b, c, d, e, f = tuple(self.coefficients)
        return a*(x**2) + b*x*y + c*(y**2) + d*x + e*y + f

while True:

    seed = int(random.random() * 1000000000)

    f = Formula()
    g = Formula()

    x, y = random.random(), random.random()

    img = Image.new("RGB", (SIZE, SIZE))

    for i in range(100000):
        #print x, y
        plotx = int(floor(x*SIZE/2))+SIZE/2
        ploty = int(floor(y*SIZE/2))+SIZE/2
        #print plotx, ploty
            img.putpixel((plotx, ploty), (255, 255, 255))
        except IndexError:
        x, y = f(x, y), g(x, y)

        if not x or not y:
            break # break out of pattern that has diminished to zero

        if x > 1 or x < -1 or y > 1 or y < -1:
            break # break out if growing too big

        img.save("a_%06d_%d.jpg" % (img_index, seed), "JPEG")
        img_index += 1
  1. Michelle W
    December 16, 2009 at 10:50 pm

    Does it work in 3D?

    • December 16, 2009 at 10:59 pm

      As far as I know it will work if you add a z component ie:
      x = f(x, y, z)
      y = g(x, y, z)
      z = h(x, y, z)
      That’s on my to do list!
      There are also plenty of different equations types that produce different results, so plenty of scope to experiment while my attention span holds out.

      I’ve greatly improved and optimised my current 2d code, and coded some image manipulation stuff. I’ll be posting that soon.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: