Cómo graficar el fractal de Mandelbrot


 

Dicen que el fractal de Mandelbrot es el objeto matemático más complejo creado (o descubierto?) por el hombre. Yo no soy un matemático de profesión asi que no puedo dar fé de ello, pero de lo que si puedo dar fé es de la belleza de los graficos que puedes obtener de él. Este es uno de los primeros intentos que hice para poder verlo por mi mismo y es lo bastante simple como para comenzar. Fué escrito en Borland C++ 3.1, usa la libreria gráfica, tiene una resolución de 640x480 con 16 colores y usa paletas personalizadas de colores. Uso una técnica de coloreado que se me ocurrió y me dió buenos resultados porque crea imágenes sin saltos bruscos de color. Si quieres código más avanzado y complejo busca en la web FRACTINT, es el mejor programa para ver fractales en DOS y viene con código fuente (aunque emplea ensamblador para sus rutinas mas críticas). También hay modernos graficadores para Windows pero los mejores son de pago y no traen código fuente. Si quieres ver mi colección personal date una vuelta por mi galeria.


mandel_1

fractal.h



//---------------------------------------------------------------
//	Fractal.h
//---------------------------------------------------------------
#ifndef _FRACTALES_H_
#define _FRACTALES_H_

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define TRUE	1
#define FALSE	0

#endif

fractal.c



//---------------------------------------------------------------
//  Fractal.c
//---------------------------------------------------------------
#include "fractal.h"
#include "mandel.h"
#include "graficos.h"

#include <dos.h>

double gf_x1;
double gf_y1;
double gf_x2;
double gf_y2;
double gn_pasos;

void Pausa()
{
  while (kbhit())
  {
    getch();
  }

  getch();
}

int main()
{
  char c;

  if (! InicializarGraficos())
  {
    exit(1);
  }

  gf_x1 = -2.5;
  gf_y1 = -1.2;
  gf_x2 = 0.7;
  gf_y2 = 1.2;
  gn_pasos = 256;

  Mandelbrot (gf_x1, gf_y1, gf_x2, gf_y2, gn_pasos);

  while (TRUE)
  {
    if (kbhit())
    {
      c = getch();

      switch (c)
      {
        case 'Q':
        case 'q':
          goto SALIR;

        case '1':
          CambiarColoresPaleta (EX_C_GRIS);
          break;

        case '2':
          CambiarColoresPaleta (EX_C_ROJO);
          break;

        case '3':
          CambiarColoresPaleta (EX_C_VERDE);
          break;

        case '4':
          CambiarColoresPaleta (EX_C_AZUL);
          break;

        case 'C':
        case 'c':
          DibujarGrilla ();
          break;

        case 'A':
        case 'a':
          GrillaIzquierda();
          break;

        case 'W':
        case 'w':
          GrillaArriba();
          break;

        case 'S':
        case 's':
          GrillaAbajo();
          break;

        case 'D':
        case 'd':
          GrillaDerecha();
          break;

        case 'Z':
        case 'z':
          Zoom (& Mandelbrot);
          break;
      }
    }

    delay (100);
  }

SALIR:

  closegraph();

  return 0;
}

mandel.h



//---------------------------------------------------------------
//  Mandel.h
//---------------------------------------------------------------
#ifndef _MANDEL_H_
#define _MANDEL_H_

#include "fractal.h"

  int Mandelbrot (double fX1,
                  double fY1,
                  double fX2,
                  double fY2,
                  int nLimite);

#endif

mandel.c



//---------------------------------------------------------------
//  Mandel.c
//---------------------------------------------------------------
//  Fractal de Mandelbrot - Esau R.O
//---------------------------------------------------------------
#include "mandel.h"
#include "graficos.h"

int Mandelbrot (double fX1,
                double fY1,
                double fX2,
                double fY2,
                int nLimite)
{
  int   max_x,  max_y,
        k,    p,    q,
        pasos,  terminar,
        color = 1;

  double  paso_x, paso_y,
          pos_x,  pos_y,
          iter_x, iter_y,
          temp_x;

  char  c;

  cleardevice();

  max_x = getmaxx();
  max_y = getmaxy();

  paso_x = (fX2 - fX1) / max_x;
  paso_y = (fY2 - fY1) / max_y;

  for (q = 64; q <= nLimite; q += 64)
  {
    for (k = 0; k <= max_x; k++)
    {
      for (p = 0; p <= max_y; p++)
      {
        pos_x = fX1 + k * paso_x;
        pos_y = fY2 - p * paso_y;

        iter_x = 0.0;
        iter_y = 0.0;

        terminar = FALSE;
        pasos = 0;

        while (! terminar)
        {
          temp_x = (iter_x * iter_x) - (iter_y * iter_y) + pos_x;

          iter_y = 2 * (iter_x * iter_y) + pos_y;

          iter_x = temp_x;

          pasos++;

          if ((iter_x * iter_x + iter_y * iter_y) >= 4.0)
          {
            terminar = TRUE;
          }

          if (pasos >= q)
          {
            terminar = TRUE;
          }
        }

        if (pasos < q)
        {

          color = (pasos - 1) % 28 + 1;

          if (color > 15)
          {
            color = 30 - color;
          }

          putpixel (k, p, color);
        }
      }

      if (kbhit())
      {
        getch();

        return FALSE;
      }
    }
  }

  return TRUE;
}

graficos.h



//---------------------------------------------------------------
//  Graficos.h
//---------------------------------------------------------------
#ifndef _GRAFICOS_H
#define _GRAFICOS_H

#include <graphics.h>

//---------------------
// modificar la ruta...
//
#define RUTA_BGI "d:\\stp\\dev\\bc\\bgi"

#define EX_C_GRIS 0
#define EX_C_AZUL 1
#define EX_C_ROJO 2
#define EX_C_VERDE  3


#define EX_MAX_GRILLA   3


void  CambiarColoresPaleta (int opc);
int   InicializarGraficos (void);
int   DibujarGrilla (void);

int   GrillaIzquierda (void);
int   GrillaDerecha (void);
int   GrillaArriba (void);
int   GrillaAbajo (void);

int   Zoom (int (* funcion)(double,
                            double,
                            double,
                            double,
                            int));

#endif

graficos.c


La manera de usar el programa puede verse en fractal.c Para mostrar la grilla la tecla [C], para salir [Q], con [1][2][3][4] cambias de paleta, para mover el sector de la grilla seleccionado [A][W][S][D] (la grilla debe estar visible), para hacer zoom en el sector de la grilla seleccionado [Z]. Al iniciar el programa se comienza a dibujar el area inicial a una baja resolucion. Para detenerlo pulsar cualquier tecla.


 

El proyecto completo se encuentra aqui: fractal.zip y el ejecutable es este: fractal_exe.zip.

 

 

Esaú Rodríguez Oscanoa

 


Diseño y coordinación : Esaú Rodriguez Oscanoa - Lima - Per�

Esta página se ve mejor en Mozilla Firefox a 1024x768


Hosted by www.Geocities.ws

1