Hola de nuevo amigos me da gusto saludarlos una vez mas y poder seguir practicando con mas aplicaciones en C++ Builder. Bueno ya casi hemos terminado con el tema de los fractales, pero aun nos quedan un par de ejemplo mas para realizar. El fractal que programaremos el día de hoy es el conocido como fractal de Sierpinski.
Bien amigos pues el día de hoy lo haremos un poco más rápido de lo normal debido a que tengo un poco de prisa, entonces me saltaré la parte de cambiarle el color a la Forma y lo único que haré en ella será colocar un botón con la leyenda "Dibujar Sierpinski". Nuestra Forma queda de la siguiente manera:
Bien ahora pasamos a la parte de código y primero nos vamos al archivo H y en la parte de declaraciones privadas declaramos las siguientes variables que utilizaremos más adelante y la definición de los métodos que declararemos más adelante y que son los que nos darán el efecto del fractal:
private: // User declarations
int depth;
int w,h;
void subTriangle(int n, float x1, float y1, float x2, float y2, float x3, float y3);
void drawSierpinski(float x1, float y1, float x2, float y2, float x3, float y3);
Ahora nos preparamos para generar el efecto del fractal de Sierpinski y primero que nada tenemos que abrir el evento OnCreate de la Forma y en él escribimos el código que tenemos a continuación:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
depth=7;
this->ClientWidth=640;
this->ClientHeight=480;
w=this->ClientWidth;
h=this->ClientHeight;
}
//---------------------------------------------------------------------------
Bien enseguida vamos a codificar los métodos definidos anteriormente primero lo haremos con el método drawSierpinski(), el código de dicho método lo tenemos a continuación:
//Esta funcion dibujara solo 1 triangulo y entonces empezara la funcion de recursividad a si mismo
void TForm1::drawSierpinski(float x1, float y1, float x2, float y2, float x3, float y3)
{
//Aqui dibujamos las 3 lineas del triangulo, uniendo los 3 puntos para generar lineas
this->Canvas->Pen->Color=(TColor)random(65000);
this->Canvas->MoveTo(x1,y1);
this->Canvas->LineTo(x2,y2);
this->Canvas->MoveTo(x2,y2);
this->Canvas->LineTo(x3,y3);
this->Canvas->MoveTo(x3,y3);
this->Canvas->LineTo(x1,y1);
//Llamamos a la funcion de recursividad y pintara el resto de los tringulos, las 3 esquinas de triangulo son simempre el centro de su posicion
subTriangle
(
1, //Esto representa la primer recursicion
(x1 + x2) / 2, //coordenada x de la primera esquina
(y1 + y2) / 2, //coordenada y de la primera esquina
(x1 + x3) / 2, //coordenada x de la segunda esquina
(y1 + y3) / 2, //coordenada y de la segunda esquina
(x2 + x3) / 2, //coordenada x de la tercera esquina
(y2 + y3) / 2 //coordenada y de la tercera esquina
);
}
//-------------------------------------------------------------------------------
Ahora codificaremos el siguiente método el cual es llamado subTriangle(), el código se muestra enseguida:
//La funcion de recursividad subtriangulo pintara todo lo que esta dentro del tringulo mayor a este
void TForm1::subTriangle(int n, float x1, float y1, float x2, float y2, float x3, float y3)
{
Sleep(10);
//Dibujamos los 3 lados del subtriangulo
this->Canvas->MoveTo(x1,y1);
this->Canvas->LineTo(x2,y2);
this->Canvas->MoveTo(x2,y2);
this->Canvas->LineTo(x3,y3);
this->Canvas->MoveTo(x3,y3);
this->Canvas->LineTo(x1,y1);
//Llamadas a si mismo 3 veces con nuevas esquinas,pero solo si el actual numero de recurrencias es menor que la profundidad maxima
if(n < depth)
{
//Triangulo mas pequeño #1
subTriangle
(
n+1, //numero de recurrencias para la siguiente llamada con aumento de 1
(x1 + x2) / 2 + (x2 - x3) / 2, //coordenada x de la primera esquina
(y1 + y2) / 2 + (y2 - y3) / 2, //coordenada y de la primera esquina
(x1 + x2) / 2 + (x1 - x3) / 2, //coordenada x de la segunda esquina
(y1 + y2) / 2 + (y1 - y3) / 2, //coordenada y de la segunda esquina
(x1 + x2) / 2, //coordendaa x de la tercera esquina
(y1 + y2) / 2 //coordenada y de la tercera esquina
);
//Triangulo mas pequeño #2
subTriangle
(
n+1, //numero de recurrencias para la siguiente llamada con aumento de 1
(x3 + x2) / 2 + (x2 - x1) / 2,
(y3 + y2) / 2 + (y2 - y1) / 2,
(x3 + x2) / 2 + (x3 - x1) / 2,
(y3 + y2) / 2 + (y3 - y1) / 2,
(x3 + x2) / 2,
(y3 + y2) / 2
);
//Triangulo mas pequeño #3
subTriangle
(
n+1, //numero de recurrencias para la siguiente llamada con aumento de 1
(x1 + x3) / 2 + (x3 - x2) / 2,
(y1 + y3) / 2 + (y3 - y2) / 2,
(x1 + x3) / 2 + (x1 - x2) / 2,
(y1 + y3) / 2 + (y1 - y2) / 2,
(x1 + x3) / 2,
(y1 + y3) / 2
);
}
}
//---------------------------------------------------------------------------------
El código de los 2 métodos anteriores es algo largo y relativamente un poco complicado sin embargo en el código se incluyen comentarios para ayudarnos a saber que hace cada parte del código y así comprender mejor el comportamiento de este fractal.
Ya para terminar solo nos resta escribir la llamada al método drawSierpinski() dentro del evento clic del Button1 (solo se hace la llamada el método drawSierpinski() ya que dentro de éste método se llama al segundo método que es el subTriangle()), el código lo tenemos enseguida:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
this->Repaint();
Sleep(1);
Button1->Enabled=false;
//Llamamos a la función de Sierpinski (funciona con cualquier esquina dentro de la pantalla)
//Asignamos las coordenadas del tringulo principal "el mas grande"
drawSierpinski(10, h - 10, w - 10, h - 10, w / 2, 10);
Button1->Enabled=true;
Button1->SetFocus();
}
//---------------------------------------------------------------------------
Bien chavos pues eso es todo lo que tenemos que hacer ahora solo compilamos y corremos nuestra aplicación y observamos el efecto que nos genera el cual es un poco tardado así que solo dejen el programa correr tranquilamente, dicho efecto debe ser como lo que tenemos enseguida:
Y bueno amigos eso fue todo por hoy, ya solo nos queda un fractal más para concluir con este tema, el fractal restante es el conocido como fractal de Landscape, y nos genera el efecto de un paisaje. Pero todo eso ya lo veremos en la siguiente ocasión. Hasta la próxima amigos!.
No hay comentarios:
Publicar un comentario