Dibujando un Fractal Mandelbrot con Ruby

Hace mucho tiempo, cuando aún me pegaba con pascal en primero de carrera empecé a descubrir los fractales. Aún recuerdo lo bien que lo pasaba con el fractint, «navegando por las profundidades de mandelbrot». Investigando un poco mas, descubrí que la formula que se utilizaba para generar dicho fractal era bastante sencilla, aún así, un software como el fractint parecía demasiado complejo.

Sin embargo, la curiosidad me picaba, ¿Qué pasaría si hiciera un programa que siguiera la formula que sirve para generar el fractal de mandelbrot?. Al fin y al cabo, la formula parecía sencilla de programar incluso para un imberbe programador 🙂

Sin más espera me puse manos a la obra y con el amado Pascal, hice un programa que supuestamente dibujaría el fractal de mandelbrot. ¿Y qué pasó?, pues ante mi asombro, al ejecutar el programa, allí estaba el famoso gráfico con forma de guitarra. ( Notese la licencia literaria, como buen programador, nada funciona a la primera 😀 )

Hace poco, trasteando con el nuevo «juguete», ruby, me volvio a picar la curiosidad de dibujar de nuevo el fractal. En esta ocasión, gracias a las utilidades que nos da un lenguaje como Ruby y una gran libreria como SDL, en pocos minutos tenia el famoso gráfico en pantalla.

Centrandonos en el lado técnico del fractal, dibujar el conjunto de mandelbrot es más o menos sencillo.

Para cada numero imaginario se desarrolla la serie z(n+1) = z(n)^2 + c. Siendo la z(0) = 0,0 y c el punto sobre el que calculamos el desarrollo de la serie. Para algunos valores de c, la serie converge, y para otros rapidamente escapa a un valor umbral que habitualmente se establece en 2+2i. Si la serie converge, el punto no pertenece a la serie de mandelbrot, y por lo tanto se pinta de negro. Para los puntos que escapan al valor umbral, según los pasos que han necesitado para escapar se les pinta de un color. Pero eso si, a todos los que escapan con el mismo numero de pasos, se les da el mismo color.

Así por ejemplo, para el punto 1+i, si desarrollamos la serie tendremos:

z(1) = (0+0i)^2 + 1+i => 1+i
z(2) = (1+i)^2 + 1+i => 1+3i
z(3) = (1+3i)^2 + 1+i => -7+7i

z(3) escapa de los límites, por lo que el punto 1+i, pertenece al conjunto de mandelbrot y se pintará con el color elegido para los números que escapan en 3 pasos.

Si hacemos esto mismo con cada punto dentro del rango 2, -2 tanto para real como para imaginario, obtendremos el gráfico que encabeza el post.

Aunque han pasado unos cuantos años, no deja de sorprenderme que un programa tan sencillo tenga como salida un gráfico tan interesante y, por que no, bonito.

Realmente el fractal mandrelbrot es apasionante, una de sus propiedades es debido a que es un fractal, se autoreplica, por lo que podemos encontrar la misma forma si vamos haciendo zoom dentro del gráfico. No voy a entrar en mas detalles, pero os dejo con el enlace de la wikipedia que describe muchos detalles de este fascinante mundo.

Para finalizar el post, os dejo con el código ruby que dibuja la imagen. Lo único que necesitais para ejecutarlo es ruby y rubysdl.

require 'sdl'

WIDTH = 600
HEIGHT = 400
REALRANGE = 2
IMRANGE = 2
MAXSTEPS = 20

def mandelbrot_steps(x, y)
	steps = 0
	newx = newy = 0
	while steps < MAXSTEPS and ( ((newx*newx) + (newy*newy)) < ((REALRANGE*REALRANGE) + (IMRANGE*IMRANGE)) ) do
		xtemp = (newx * newx) - (newy * newy) + x
		newy = 2 * newx * newy + y
		newx = xtemp
		steps+=1
	end

	return steps
end

SDL.init SDL::INIT_VIDEO
screen = SDL.set_video_mode WIDTH, HEIGHT, 24, SDL::HWSURFACE

pallete = Array.new
pallete[0] = screen.format.mapRGB(0,0,0)
pallete[1] = screen.format.mapRGB(40,36,196)
pallete[2] = screen.format.mapRGB(30,144,255)
pallete[3] = screen.format.mapRGB(0,0,128)
pallete[4] = screen.format.mapRGB(0,255,0)
pallete[5] = screen.format.mapRGB(0,255,255)
pallete[6] = screen.format.mapRGB(0,0,255)
pallete[7] = screen.format.mapRGB(255,255,255)
pallete[8] = screen.format.mapRGB(255,100,255)
pallete[9] = screen.format.mapRGB(0,255,255)
pallete[10] = screen.format.mapRGB(100,255,100)

(-WIDTH/2).upto WIDTH/2 do |x|
	(-HEIGHT/2).upto HEIGHT/2 do |y|
		scaledX = (x * 2)/(WIDTH/2).to_f - 0.7
		scaledY = (y * 2)/(HEIGHT/2).to_f
		color = pallete[0]
		steps = mandelbrot_steps scaledX, scaledY
		color =  pallete[steps % 10] if steps < MAXSTEPS
		screen.put_pixel x+(WIDTH/2), y+(HEIGHT/2), color
	end
end

running = true
while running do
	while event = SDL::Event2.poll do
		case event
		when SDL::Event2::Quit
			running = false
		end
	end

	screen.flip
end

SDL.quit

1 Responses to Dibujando un Fractal Mandelbrot con Ruby

  1. BLOJER dice:

    Compresión fractal…

    Imagen: «What is your formula? your equation? your algorithm?», Edge 226. «La autosimilitud del conjunto M/conjunto de Mandelbrot se pone de manifiesto en las infinitas copias de sí mismo que contiene, copias todas ligeramente distintas, pero todas c…

Replica a BLOJER Cancelar la respuesta