domingo, 30 de octubre de 2011

Transformaciones bidimensionales


A la hora de graficar, el eje X se muestra como en plano cartesiano pero el eje Y esta invertido, lo cual quiere decir que conforme vaya aumentando el valor de Y este va hacie el fondo de la ventana.
A continuacion se muestra el codigo para invertir el eje Y, utilizando la clase VentanaPuerto, la cual tambien
no sirve a la hora de manejar las coordenadas mundiales y las coordenadas de los dispositivos.


class VentanaPuerto
{
        private:
        float xWmin, yWmin, xWmax, yWmax;
        int xPvmin, yPvmin, xPvmax, yPvmax;

        public:
        void Ventana(float xW1, float yW1, float xW2, float yW2);
        void Puerto_Vision(int xPv1, int yPv1, int xPv2, int yPv2);
        void Mapeo(float x1, float y1, int *xt1, int *yt1, int L, int M);

};


void VentanaPuerto::Ventana(float xW1, float yW1, float xW2, float yW2)
{
        xWmin = xW1; //0
        yWmin = yW1; //0

        xWmax = xW2;  //500
        yWmax = yW2;   //500
}

void VentanaPuerto::Puerto_Vision(int xPv1, int yPv1, int xPv2, int yPv2)
{
        xPvmin =  xPv1;
        yPvmin =  yPv1;

        xPvmax =  xPv2;  
        yPvmax =  yPv2;  
}

void VentanaPuerto::Mapeo(float x1, float y1, int *xt1, int *yt1, int L, int M)
{
        float sx, sy;

        sx = (xPvmax - xPvmin) / (xWmax - yWmin);  
        sy = (yPvmax - yPvmin) / (yWmax - yWmin);  

        *xt1 = floor(sx * (x1 - xWmin) + xPvmin + L + 0.5);
        *yt1 = floor(sy * (yWmin - y1) - yPvmin + M + 0.5);

}


void __fastcall TForm1::Button6Click(TObject *Sender)
{
        int fig[4][2] = {{1, 1},
                         {3, 1},
                         {2, 3},
                         {1, 1}};

        VentanaPuerto vp;

        vp.Ventana(0, 0, 22, 28);

         Canvas->Rectangle(100, 100, 321, 380);
         vp.Puerto_Vision(100, 100, 321, 380);

        int L = 0;
        int M = 190 + 290;

        int xx1, yy1, xx2, yy2;

        vp.Mapeo(fig[0][0],fig[0][1], &xx1, &yy1, L, M);
        Canvas->MoveTo(xx1, yy1);

        for(int i = 1; i < 4; i++)
        {
            vp.Mapeo(fig[i][0], fig[i][1], &xx1, &yy1, L, M);
            Canvas->LineTo(xx1, yy1);
        }

}

domingo, 9 de octubre de 2011

Trazo de Espirales



Codigo para trazar espirales.


void TForm1::Espiral()
{
        int xc = ClientWidth / 2, yc = ClientHeight / 2, radio = 5;  // radio valor a cambiar
        double dos_pi = M_PI * 2.0;
        int cont  = 0;
        double dth, cth, sth, x, y, x_temp, xt, yt;

        dth = dos_pi / (16 * radio); // cambiar 16 a 2 y 4
        cth = cos(dth);
        sth = sin(dth);

        x = 0.0; y = radio;
        xt = xc + x; yt = yc + y;

        do
        {
            x_temp = x;
            x = x * cth - y * sth;
            y = y * cth + x_temp * sth;

            if(x > 0)
              x += 0.5;
            else
              x -= 0.5;

             if(y > 0)
              y += 0.5;
            else
              y -= 0.5;

            Canvas->Pixels[floor(xt + 0.5)][floor(yt + 0.5)] = clRed;
            linea_DDA(floor(xt + 0.5), floor(yt + 0.5), floor(xc + x + 0.5),
            floor(yc + y + 0.5));

            xt = xc + x;
            yt = yc + y;
            cont++;
            Sleep(20);

        }while(cont <= 350);

}



void TForm1::Espiral2()
{
        int xc = ClientWidth / 2, yc = ClientHeight / 2;
        float radio =  1.0;     // valores a cambiar
        double th, x, y, xt, yt;

        th = 0.0;               // valores a cambiar

        x = radio * cos(th);
        y = radio * sin(th);
        xt = xc + x;
        yt = yc + y;

        while(radio < 250)
        {
            th += 0.1;
            radio += 0.9;

            x = radio * cos(th);
            y = radio * sin(th);

            g->linea_DDA(floor(xt + 0.5), floor(yt + 0.5), floor(xc + x + 0.5),
            floor(yc + y + 0.5));

            xt = xc + x;
            yt = yc + y;

            Sleep(5);
        }
}

Trazo de Circunferencias



Los parametros basicos que definen una circunferencia son las coordenadas del centro (xc, yc) y el
radio. Podemos expresar la ecuacion de la circunferencia de varias formas.

Abajo el codigo para hacer un circulo mediante coordenadas polares, por segmentos e incrementos
de angulos.


void TForm1::Circ_Coord_Polares(int xc, int yc, int r)
{
        float dt, ct, st, x, y, xtemp;

        dt = 1.0 / r;

        ct = cos(dt);
        st = sin(dt);

        x = 0;
        y = r;

        while(y >= x)
        {
           Canvas->Pixels[floor(xc + x)+ 0.5][floor(yc + y)+ 0.5] = clRed;
           Canvas->Pixels[floor(xc - x)+ 0.5][floor(yc + y)+ 0.5] = clRed;
           Canvas->Pixels[floor(xc + x)+ 0.5][floor(yc - y)+ 0.5] = clRed;
           Canvas->Pixels[floor(xc - x)+ 0.5][floor(yc - y)+ 0.5] = clRed;

           xtemp = x;

           x = x * ct - y * st;
           y = y * ct + xtemp * st;
        }
}


void TForm1::Circulo_x_Segmentos(int xc, int yc, int radio)
{
        double dos_pi = M_PI * 2;
        double dth, ct, st, x, y, xtemp;

        if(radio != 0)
        {
            dth = dos_pi / (16 * radio);
            ct = cos(dth);
            st = sin(dth);
            x = 0;
            y = radio;

            for(int i = 0;i <=(16 * radio); i++)
            {
               xtemp = x;
               x = x * ct + y *st;
               y = y * ct - xtemp * st;
               Canvas->Pixels[floor(x + xc + 0.5)][floor(y + yc + 0.5)] = clBlue;
            }
        }
}


void TForm1::Circulo_incremento_angulo(int xc, int yc, int radio)
{
          int x, y;

          for(int grados = 0; grados < 360; grados++)
          {
              x = xc + radio * cos (grados/180.0 * M_PI);
              y = yc + radio * sin (grados/180.0 * M_PI);
              Canvas->Pixels[x][y] = clBlack;
              Sleep(30);
          }
}

domingo, 2 de octubre de 2011

Algoritmo linea dda(algoritmo diferencial digital)


Este programa para trazar una linea recta basado en al algoritmo dda. Este, sirve para calcular posiciones de pixeles a lo largo de una linea recta. Abajo se encuentra el codigo de la aplicacion
de este algoritmo. Las lineas en el programa se pueden hacer con el click y arrastre del mouse o ya sea
insertando las coordenas manualmente.


class TForm1 : public TForm
{
__published: // IDE-managed Components
        TPanel *Panel1;
        TLabel *Label1;
        TButton *Button1;
        TEdit *Edit1;
        TLabel *Label2;
        TEdit *Edit2;
        TLabel *Label3;
        TEdit *Edit3;
        TLabel *Label4;
        TEdit *Edit4;
        TPaintBox *PaintBox1;
        TButton *Button2;
        TComboBox *ComboBox1;
        TLabel *Label5;
        void __fastcall Button1Click(TObject *Sender);
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall PaintBox1MouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y);
        void __fastcall PaintBox1MouseUp(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y);
        void __fastcall Button2Click(TObject *Sender);
private: // User declarations
        Graficos *g;
        int x1, y1, x2, y2;

void linea_DDA(int x1, int y1, int x2, int y2);
public: // User declarations
        __fastcall TForm1(TComponent* Owner);
};



void TForm1::linea_DDA(int x1, int y1, int x2, int y2)
{
        int dx, dy, steps, k;
        float x_inc, y_inc, x, y;

        dx = x2 - x1;
        dy = y2 - y1;

        if(abs(dx) > abs(dy))
        {
           steps = abs(dx);
        }
        else
        {
           steps = abs(dy);
        }

        x_inc = (float) dx / steps;
        y_inc = (float) dy / steps;

        x = x1;
        y = y1;

        //Putpixel(floor(x), floor(y), 1);
        Form1->Canvas->Pixels[x][y] = clBlack;

        for(k = 1; k < steps + 1 ; k++)
        {
            x = x + x_inc;
            y = y + y_inc;
            //Putpixel(x, y, 1);
            PaintBox1->Canvas->Pixels[x][y] = clBlack;
        }
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
     int x1 = Edit1->Text.ToInt();
     int y1 = Edit2->Text.ToInt();
     int x2 = Edit3->Text.ToInt();
     int y2 = Edit4->Text.ToInt();
     TColor color;

     if(ComboBox1->Text == 'rojo')
     {
       color = color & 255;
     }
   
     g->linea_DDA(x1, y1, x2, y2, color);

     //linea_DDA(x1, y1, x2, y2);

     //int x1 = Edit1->Text.ToIntDef(10); por si el usuario no pone un valor en Edit
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
        g = new Graficos(PaintBox1->Canvas);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::PaintBox1MouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
        Edit1->Text = x1 = X;
        Edit2->Text = y1 = Y;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::PaintBox1MouseUp(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
        Edit3->Text = x2 = X;
        Edit4->Text = y2 = Y;
        g->linea_DDA(x1, y1, x2, y2);

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

void __fastcall TForm1::Button2Click(TObject *Sender)
{
       Refresh(); //      
}
//---------------------------------------------------------------------------

domingo, 25 de septiembre de 2011

Escena Fractal


En este fractal se utilzan 3 metodos para dibujarlo, los cuales en 2 de ellos se usa recursividad. Abajo el codigo. El fractal se puede generar mediante un timer (automaticamente) o con un boton. Usted elige.


class TForm1 : public TForm
{
__published: // IDE-managed Components
        TPaintBox *PaintBox1;
        TButton *Button1;
        TTimer *Timer1;
        void __fastcall Button1Click(TObject *Sender);
        void __fastcall Timer1Timer(TObject *Sender);
private: // User declarations

void subdivide(int first, int last, double std, double ratio);
void fractal(int y1, int y2, int maxlevel, double h, double scale);
void draw_fractal(void);
public: // User declarations
        __fastcall TForm1(TComponent* Owner);
};


//---------------------------------------------------------------------------

#include <vcl.h>
#include <math.h>
#pragma hdrstop

#include "EscenaFractal.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

const int MAXSIZE = 1000;
const int MAXLEVEL = 6;
double frct1[MAXSIZE];
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void TForm1::subdivide(int p1, int p2, double std, double ratio)
{
        int midpnt;
        double stdmid;

        midpnt = (p1 + p2) / 2;

        if(midpnt != p1 && midpnt != p2)
        {
          frct1[midpnt] = (frct1[p1] + frct1[p2]) / 2 +
          (double)((random(16) - 8)) / 8.0 * std;

          stdmid = std * ratio;

          subdivide(p1, midpnt, stdmid, ratio);
          subdivide(midpnt, p2, stdmid, ratio);
        }
}

void TForm1::fractal(int y1, int y2, int maxlevel, double h, double scale)
{
        int first, last;
        double ratio, std;

        first = 0;
        last = (int)pow(2.0,(double)maxlevel);
        frct1[first] = y1;
        frct1[last] = y2;
        ratio = 1.0 / pow(2.0,h);
        std = scale * ratio;
        subdivide(first, last, std, ratio);
}

void TForm1::draw_fractal(void)
{
        int i, x, xinc, l;
        //int cw = Form1->ClientWidth;

        l = (int)pow(2.0, (double)MAXLEVEL);
        xinc = ClientWidth / l * 3 / 2;
        Form1->Canvas->MoveTo(0, 100);

        for(i = 0, x = 0; i < l; i++, x +=xinc)
        {
          Form1->Canvas->LineTo(x, (int)frct1[i]);
        }

}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        randomize();
        PaintBox1->Refresh();
        PaintBox1->Canvas->Rectangle(0,0, PaintBox1->Width, PaintBox1->Height);
        PaintBox1->Canvas->Brush->Color = clSkyBlue;
        fractal(100,100, MAXLEVEL, 0.5, 50.0);
        draw_fractal();
        PaintBox1->Canvas->FloodFill(1,1, clBlack, fsBorder);

        PaintBox1->Canvas->Brush->Color = clBlue; //(TColor);
        fractal(170, 170, MAXLEVEL, 0.9, 30.0);
        draw_fractal();
        PaintBox1->Canvas->FloodFill(1, 240, clBlack, fsBorder);

        PaintBox1->Canvas->Brush->Color = clYellow; //;(TColor)SUN;
        PaintBox1->Canvas->Ellipse(250, 20, 290, 60);
        PaintBox1->Canvas->FloodFill(270, 50, clBlack, fsBorder);

        PaintBox1->Canvas->Brush->Color = clGreen;
        PaintBox1->Canvas->FloodFill(270, 150, clBlack, fsBorder);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    randomize();
        PaintBox1->Refresh();
        PaintBox1->Canvas->Rectangle(0,0, PaintBox1->Width, PaintBox1->Height);
        PaintBox1->Canvas->Brush->Color = clSkyBlue;
        fractal(100,100, MAXLEVEL, 0.5, 50.0);
        draw_fractal();
        PaintBox1->Canvas->FloodFill(1,1, clBlack, fsBorder);

        PaintBox1->Canvas->Brush->Color = clBlue; //(TColor);
        fractal(170, 170, MAXLEVEL, 0.9, 30.0);
        draw_fractal();
        PaintBox1->Canvas->FloodFill(1, 240, clBlack, fsBorder);

        PaintBox1->Canvas->Brush->Color = clYellow; //;(TColor)SUN;
        PaintBox1->Canvas->Ellipse(250, 20, 290, 60);
        PaintBox1->Canvas->FloodFill(270, 50, clBlack, fsBorder);

        PaintBox1->Canvas->Brush->Color = clGreen;
        PaintBox1->Canvas->FloodFill(270, 150, clBlack, fsBorder);
}
//---------------------------------------------------------------------------

Fractal de Mandel


Codigo del fractal de Mandel. Fractal hecho a base de pixeles rojos. El codigo es muy corto y facil de
implementar, aqui abajo esta.


class TForm1 : public TForm
{
__published: // IDE-managed Components
        TTimer *Timer1;
        void __fastcall Timer1Timer(TObject *Sender);
private: // User declarations
public: // User declarations

int maxX, maxY, Limite, i, j, Pasos, Terminar;
double PasoX, PasoY, PosX, PosY, OrigX, OrigY,
DimX, DimY, IterX, IterY, TempX;

        __fastcall TForm1(TComponent* Owner);
};



void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
     maxX = ClientWidth;
     maxY = ClientHeight;
     Limite = 100;
     OrigX = -2.0;
     OrigY = -1.25;
     DimX = 0.5;
     DimY = 1.25;

     PasoX = (DimX - OrigX) / maxX;
     PasoY = (DimY - OrigY) / maxY;

     for(i = 0; i <= maxX; i++)
     {
        for(j =0; j <= maxY; j++)
        {
          PosX = OrigX + i * PasoX;
          PosY = OrigY + j * PasoY;

          IterX = 0.0;
          IterY = 0.0;

          Terminar = Pasos = 0;

          while(!Terminar)
          {
             TempX = (IterX * IterX) - (IterY * IterY) + PosX;
             IterY = 2 * (IterX * IterY) + PosY;
             IterX = TempX;
             Pasos++;

             if(hypot(fabs( IterX), fabs( IterY)) >= 2.0)
             {
                Terminar++;
             }

             if(Pasos >= Limite)
             {
               Terminar++;
             }

             if(Form1->OnKeyPress)
             {
                i = maxX;
                j = maxY;
                Terminar++;
             }
          }

          if(Pasos < Limite)
          {
            Canvas->Pixels[i][j] = clRed;
          }

        }
     }

}

jueves, 22 de septiembre de 2011

Fractal de Henon


Codigo de fractal de Henon.



void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
        EscalaX = 1;
        EscalaY = 1;
        maxX = ClientWidth;
        maxY = ClientHeight;
        DespX = 0;
        DespY = 0;
        ExtranioConfinador();
        Sleep(100);
}
//---------------------------------------------------------------------------

void TForm1::ExtranioConfinador()
{
        int a, i, Color, PosX, PosY;
        double Xant, Xnuevo, Yant, Ynuevo;

        Xant = Xnuevo = Yant = Ynuevo = 0;

        for(Color = 1; Color <=5; Color++)
        {
           for(i = i; i <= 0x02FF; i++)
           {
              Xnuevo = Yant + 1 - (1.4 * Xant * Xant);
              Ynuevo = 0.3 * Xant;

              PosX = (Xnuevo * maxX / 3 * EscalaX) + maxX / 2 + DespX;

              PosY = (Ynuevo * maxY *EscalaY) + maxY / 2 + DespY;

              if((PosX >= 0) && (PosY <= maxX) && (PosY >= 0) && (PosY <= maxY))
              {
                Canvas->Pixels[PosX][PosY] = clRed;
              }

              Yant = Ynuevo;
              Xant = Xnuevo;
           }
        }

}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        Timer1->Enabled = true;      
}
//---------------------------------------------------------------------------

archivo .h

class TForm1 : public TForm
{
__published: // IDE-managed Components
        TButton *Button1;
        TTimer *Timer1;
        void __fastcall Timer1Timer(TObject *Sender);
        void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public: // User declarations
        int maxX, maxY;
        double EscalaX, EscalaY, DespX, DespY;
        void ExtranioConfinador();
        __fastcall TForm1(TComponent* Owner);
};