He hecho un pequeño código en python para hacer pruebecillas, la verdad que con muy poco código se obtienen imágenes bastante bonitas, de hecho estoy pensando en imprimir alguna y ponerla de poster. Se generan imágenes de este pelo:

El código, necesita PIL y python 2.4 y he dejado algunas funciones para generar animaciones (con un par de hilos para -intentar- aprovechar mi dual core) y 3 ó 4 test de resultados chulos. El código generado HTML a partir del .py usando, como no, vim, la putada es que blogger te mete saltos de linea y hay que quitar los tags br, con un simple replace basta.
import Image;
from threading import Thread;
SIZEX = 1024;
SIZEY = int(SIZEX*2.0/3.0);
NFRAMES = 50;
ZOOMSTEP = 1.0;
def get_color(xx,yy):
x = x0 = xx;
y = y0 = yy;
colour = 0;
iteration = 0
maxiteration = 600
while ( x*x + y*y < 4 and iteration < maxiteration ):
tx = x*x - y*y + x0;
ty = 2*x*y + y0;
x = tx;
y = ty;
iteration = iteration + 1;
colour = float(iteration)/maxiteration;
return colour;
class Palete:
def __init__(self):
self._colors = []
pass;
def addColor(self,color, t):
self._colors.append((color,t));
def getColor(self,t):
#search for color
i = 0;
while(self._colors[i][1] < t):
i+=1;
if(i == 0):
return self._colors[0][0];
else:
t0 = self._colors[i-1][1];
t1 = self._colors[i][1]
dist = t1-t0;
d = (t-t0)/dist;
c0 = self._colors[i-1][0];
c1 = self._colors[i][0];
#print d
color = (c0[0] + d*(c1[0] - c0[0]),
c0[1] + d*(c1[1] - c0[1]),
c0[2] + d*(c1[2] - c0[2]));
return color;
def get_img_fractal(zoom, px,py, palete):
im = Image.new("RGB", (SIZEX,SIZEY))
for x in range(SIZEX):
for y in range(SIZEY):
t = get_color(px + zoom*(-2.0 + 3.0*(float(x)/SIZEX)) ,py + zoom*(-1.0 + 2.0*(float(y)/SIZEY)));
color = palete.getColor(t);
im.putpixel((x,y),(255*color[0],255*color[1],255*color[2]));
return im;
class Fractal(Thread):
def __init__ (self,fractals):
Thread.__init__(self)
self._fractals = fractals;
def run(self):
p = Palete();
p.addColor((1.0,1.0,1.0),0.0);
p.addColor((1.0,0.0,0.0),0.5);
p.addColor((1.0,1.0,1.0),1.0);
for x in self._fractals:
print "generating %.3d.png" % x[3];
get_img_fractal(x[0],x[1],x[2],p).save("%.3d.png" % x[3]);
def animation():
zoom = 1.0;
it = 0;
fractals = [];
for n in range(NFRAMES):
fractals.append((zoom,-0.77028065155993652446, -0.11144667326007166574,n));
zoom = zoom/2.0;
it+=1;
#launch two threadç
f1 = Fractal(fractals[:len(fractals)/2]);
f2 = Fractal(fractals[len(fractals)/2:-1]);
f1.start();
f2.start();
def testColoring():
p = Palete();
p.addColor((1.0,1.0,1.0),0.0);
p.addColor((1.0,0.0,0.0),0.5);
p.addColor((1.0,1.0,1.0),1.0);
get_img_fractal(0.4,-0.77028065155993652446, -0.11144667326007166574,p).save("coloring.png");
def testColoring2():
p = Palete();
p.addColor((0.0,0.0,0.0),0.0);
p.addColor((145.0/255.0,165.0/255.0,192.0/255.0),0.5);
p.addColor((1.0,1.0,1.0),1.0);
get_img_fractal(0.0001,-0.77028065155993652446, -0.11144667326007166574,p).save("coloring2.png");
def testColoring3():
p = Palete();
p.addColor((1.0,1.0,1.0),0.0);
p.addColor((145.0/255.0,165.0/255.0,192.0/255.0),0.5);
p.addColor((0.0,125.0/255.0,244.0/255.0),1.0);
get_img_fractal(0.0001,-0.77028065155993652446, -0.11144667326007166574,p).save("coloring3.png");
def testColoring4():
p = Palete();
p.addColor((0.0,0.0,0.0),0.0);
p.addColor((145.0/255.0,165.0/255.0,192.0/255.0),0.5);
p.addColor((1.0,1.0,1.0),1.0);
get_img_fractal(0.00001,-0.26605838294940658357,-0.65123057178473777796,p).save("coloring4.png");
#testColoring2();
#testColoring3();
testColoring4();
#animation();