domingo, 27 de noviembre de 2011

fractales



#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

//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
        );
}
//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
        );
    }
}




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();

}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
        depth=7;
        this->ClientWidth=640;
        this->ClientHeight=480;
        w=this->ClientWidth;
        h=this->ClientHeight;    
}
//---------------------------------------------------------------------------

No hay comentarios:

Publicar un comentario