Bienvenidos

En este blog se publicaran proyectos en c++, les doy la bienvenida y espero sea de ayuda para ustedes este espacio, no olviden comentar!

domingo, 5 de febrero de 2012

Gráficos Básicos en 3D

Utilización y manipulación de Cubos en los 3 ejes X, Y, Z

  • Rotar
  • Trasladar
  • Escalar

Figura Basica en x, y, z

Figura rotada en el eje Y

Figura rotada en el eje Y

Escalamiento de cubos de forma individual


Traslación eje Z

Traslación eje Z

Traslación eje Z


CODIGO C++

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <Math.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
    tx = ty = tz = 0;
    rx = ry = rz = 90;
    ex = ey = ez = 1;
}
//---------------------------------------------------------------------------
float TForm1::Radianes(float angulo)
{
         float rad = angulo * M_PI / 180;
         return rad;
}
void TForm1::AsignaValores()
{
        Puntos3D cuboAux[] = {{100, 50, 0, 0},  {200,50,0,1},
                              {200, 600, 0, 1}, {100,600,0,1},
                              {100, 50,0,1},    {100,50,100,1},
                              {200, 50,100,1},  {200,600,100,1},
                              {200, 600,0,1},   {200,50,0,0},
                              {200, 50,100,1},  {100,50,100,0},
                              {100, 600,100,1}, {100,600,0,1},
                              {100, 600,100,0}, {200,600,100,1},

                              {500, 50, 0, 0},  {600,50,0,1},
                              {600, 600, 0, 1}, {500,600,0,1},
                              {500, 50,0,1},    {500,50,100,1},
                              {600, 50,100,1},  {600,600,100,1},
                              {600, 600,0,1},   {600,50,0,0},
                              {600, 50,100,1},  {500,50,100,0},
                              {500, 600,100,1}, {500,600,0,1},
                              {500, 600,100,0}, {600,600,100,1},

                              {200, 500, 0, 0},  {500,500,0,1},
                              {500, 600, 0, 1}, {200,600,0,1},
                              {200, 500,0,1},    {200,500,100,1},
                              {500, 500,100,1},  {500,600,100,1},
                              {500, 600,0,1},   {500,500,0,0},
                              {500, 500,100,1},  {200,500,100,0},
                              {200, 600,100,1}, {200,600,0,1},
                              {200, 600,100,0}, {500,600,100,1},

                              {200, 300, 0, 0},  {500,300,0,1},
                              {500, 400, 0, 1}, {200,400,0,1},
                              {200, 300,0,1},    {200,300,100,1},
                              {500, 300,100,1},  {500,400,100,1},
                              {500, 400,0,1},   {500,300,0,0},
                              {500, 300,100,1},  {200,300,100,0},
                              {200, 400,100,1}, {200,400,0,1},
                              {200, 400,100,0}, {500,400,100,1}  };

        cubo = new Puntos3D[64];
        for(int i=0;i<64;i++)
                cubo[i]=cuboAux[i];
}

void TForm1::InicializaPuerto()
{
        SetMapMode(PaintBox1->Canvas->Handle,MM_LOMETRIC);
        SetViewportOrgEx(PaintBox1->Canvas->Handle,0,PaintBox1->Height,NULL);
}
//---------------------------------------------------------------------------
bool band=true;
void TForm1::DibujaCubo()
{
        //float phi = TB2->Position;
        float phi = 30;
        POINT ArribaIzq, AbajoDer;
        ArribaIzq.x=0;     ArribaIzq.y=0;
        AbajoDer.x=PaintBox1->Width;
        AbajoDer.y=PaintBox1->Height;
        DPtoLP(PaintBox1->Canvas->Handle,&ArribaIzq,1);
        DPtoLP(PaintBox1->Canvas->Handle,&AbajoDer,1);
        PaintBox1->Canvas->Pen->Color = clBlack;
        //PaintBox1->Canvas->Brush->Color = clSkyBlue;
        PaintBox1->Canvas->Rectangle(ArribaIzq.x,ArribaIzq.y,AbajoDer.x,AbajoDer.y);
        //DIBUJAR EJES X,Y
        PaintBox1->Canvas->Pen->Color = clWhite;

        PaintBox1->Canvas->MoveTo(ArribaIzq.x,10);
        PaintBox1->Canvas->LineTo(AbajoDer.x,10);
        PaintBox1->Canvas->MoveTo(10,ArribaIzq.y);
        PaintBox1->Canvas->LineTo(10,AbajoDer.y);
        //DIBUJAR EJE Z
        int zx = AbajoDer.y * cos(Radianes(phi))+10;
        int zy = AbajoDer.y * sin(Radianes(phi))+10;
        PaintBox1->Canvas->MoveTo(zx,zy);
        zx = ArribaIzq.y * cos(Radianes(phi))+10;
        zy = ArribaIzq.y * sin(Radianes(phi))+10;
        PaintBox1->Canvas->LineTo(zx,zy);
        if(band==true)
        {
        AsignaValores();
        band=false;
        }
        PaintBox1->Canvas->Pen->Color = clBlack;
        PaintBox1->Canvas->Pen->Width =  4;
        for(int i=0;i<64;i++)
        {
                if(i<5)
                   PaintBox1->Canvas->Pen->Color = clLime;
                else
                   PaintBox1->Canvas->Pen->Color = clAqua;
               // Sleep(500);
                if(cubo[i].opcion)
                        LineTo3D(cubo[i].x + tx,cubo[i].y+ty,cubo[i].z+tz, Radianes(45.0),Radianes(phi));
                else
                        MoveTo3D(cubo[i].x + tx,cubo[i].y+ty,cubo[i].z+tz, Radianes(45.0),Radianes(phi));
        }

}
//---------------------------------------------------------------------------
void TForm1::LineTo3D(int x, int y, int z, double alpha, double phi)
{
        int xp, yp, l;
        float tanalpha;
        //alpha = TB1->Position;
        //phi = TB2->Position;
        if((tanalpha = tan(alpha)) != 0)
                l=(int)(z/tanalpha);
        else
                l=0;
        xp=x+l*cos(phi);
        yp=y+l*sin(phi);
        PaintBox1->Canvas->LineTo(xp,yp);
}
//---------------------------------------------------------------------------
void TForm1::MoveTo3D(int x, int y, int z, double alpha, double phi)
{
        int xp, yp, l;
        float tanalpha;
        //alpha = TB1->Position;
        //phi = TB2->Position;
        if((tanalpha = tan(alpha)) != 0)
                l=(int)(z/tanalpha);
        else
                l=0;
        xp=x+l*cos(phi);
        yp=y+l*sin(phi);
        PaintBox1->Canvas->MoveTo(xp,yp);
}
bool band1=true;
void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
{
      if(band1==true)
       {
        InicializaPuerto();
        DibujaCubo();
        band1=false;
       }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key)
{
       switch(Key)
        {
                case 'x':
                        tx-=10;
                        InicializaPuerto();
                        DibujaCubo();
                        break;
                case 'X':
                        tx+=10;
                        InicializaPuerto();
                        DibujaCubo();
                        break;
                case 'y':
                        ty-=10;
                        InicializaPuerto();
                        DibujaCubo();
                        break;
                case 'Y':
                        ty+=10;
                        InicializaPuerto();
                        DibujaCubo();
                        break;
                case 'z':
                        tz-=10;
                        InicializaPuerto();
                        DibujaCubo();
                        break;
                case 'Z':
                        tz+=10;
                        InicializaPuerto();
                        DibujaCubo();
                        break;

       case 'a':
       case 'A':
         ex += 0.1;
        Escalacion(ex, 1, 1);
        InicializaPuerto();
        DibujaCubo();

       break;

       case 's':
       case 'S':
         ex -= 0.1;
         Escalacion(ex, 1, 1);
         InicializaPuerto();
         DibujaCubo();
       break;

       case 'w':
       case 'W':
         ey += 0.1;
         Escalacion(1, ey, 1);
         InicializaPuerto();
         DibujaCubo();
       break;

       case 'e':
       case 'E':
         ey -= 0.1;
         Escalacion(1, ey, 1);
         InicializaPuerto();
         DibujaCubo();
       break;

       case 'r':
       case 'R':
         ez += 0.1;
         Escalacion(1, 1, ez);
         InicializaPuerto();
         DibujaCubo();
       break;

       case 'd':
       case 'D':
         ez -= 0.1;
         Escalacion(1, 1, ez);
         InicializaPuerto();
         DibujaCubo();
       break;


       case 'g':
       case 'G':
        
         rx--;
         PaintBox1->Repaint();
         RotarX(rx);

       break;

       case 'h':
       case 'H':
         rx++;
         PaintBox1->Repaint();
         RotarX(rx);
       break;

       case 'j':
       case 'J':
         ry--;
         PaintBox1->Repaint();
         RotarY(ry);

       break;

       case 'k':
       case 'K':
         ry++;
         PaintBox1->Repaint();
         RotarY(ry);

       break;

       case 'l':
       case 'L':
         rz--;
         PaintBox1->Repaint();
         RotarZ(rz);

       break;

       case 'm':
       case 'M':
         rz++;
         PaintBox1->Repaint();
         RotarZ(rz);

       break;
       //-----------------------


        }
        //InicializaPuerto();
        //DibujaCubo();
      //  PaintBox1->Refresh();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
      switch(Key)
        {
                case VK_RIGHT: tx+=10;
                           break;
                case VK_LEFT: tx-=10;
                           break;
                case VK_UP: ty+=10;
                           break;
                case VK_DOWN: ty-=10;
                           break;
                case VK_HOME: tz+=10;
                           break;
                case VK_END: tz-=10;
                           break;

         }
        PaintBox1->Refresh();
       InicializaPuerto();
        DibujaCubo();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
   this->DoubleBuffered = true;
   this->Focused();



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

void TForm1::Escalacion(double Ex, double Ey, double Ez)
{

    double xc = cubo[0].x + (cubo[1].x - cubo[0].x) / 2;
    double yc = cubo[0].y + (cubo[2].y - cubo[0].y) / 2;
    double zc = cubo[0].z + (cubo[5].z - cubo[0].z) / 2;

    for(int i = 0; i < 16; i++)
    {
        cubo[i].x = xc + (cubo[i].x - xc) * Ex;
        cubo[i].y = yc + (cubo[i].y - yc) * Ey;
        cubo[i].z = zc + (cubo[i].z - zc) * Ez;
    }
}

void TForm1::RotarX(double g)
{
      InicializaPuerto();
    int yc = (cubo[0].y + cubo[2].y) / 2;
    int zc = (cubo[0].z + cubo[5].z) / 2;
    int x,y,z;
    for(int i = 0; i < 68; i++)
    {
        x = cubo[i].x;
        y = ((cubo[i].y - yc) * cos(g))  + ((cubo[i].z - zc) * -sin(g)) + yc;
        z = ((cubo[i].y - yc) * sin(g)) + ((cubo[i].z - zc) * cos(g)) + zc;

        if(i < 6)
            PaintBox1->Canvas->Pen->Color = clLime;
        else
            PaintBox1->Canvas->Pen->Color = clAqua;

        if(cubo[i].opcion)
            LineTo3D(x, y, z, Radianes(45.0),Radianes(30));
        else
            MoveTo3D(x, y, z, Radianes(45.0),Radianes(30));
    }
}
//---------------------------------------------------------------------------
void TForm1::RotarY(double g)
{
     InicializaPuerto();
    int xc = (cubo[0].x + cubo[1].x) / 2;
    int zc = (cubo[0].z + cubo[5].z) / 2;

    for(int i = 0; i < 64; i++)
    {
        int x = ((cubo[i].x - xc) * cos(g))  + ((cubo[i].z - zc) * -sin(g)) + xc;
        int y = cubo[i].y;
        int z = ((cubo[i].x - xc) * sin(g)) + ((cubo[i].z - zc) * cos(g)) + zc;

        if(i < 6)
            PaintBox1->Canvas->Pen->Color = clLime;
        else
            PaintBox1->Canvas->Pen->Color = clAqua;

        if(cubo[i].opcion)
            LineTo3D(x, y, z, Radianes(45.0),Radianes(30));
        else
            MoveTo3D(x, y, z, Radianes(45.0),Radianes(30));
    }
}
//---------------------------------------------------------------------------
void TForm1::RotarZ(double g)
{
     InicializaPuerto();
    int xc = (cubo[0].x + cubo[1].x) / 2;
    int yc = (cubo[0].y + cubo[2].y) / 2;
    //int zc = (cubo[0].z + cubo[5].z) / 2;

    for(int i = 0; i < 16; i++)
    {
        int x = ((cubo[i].x - xc) * cos(g))  + ((cubo[i].y - yc) * -sin(g)) + xc;
        int y = ((cubo[i].x - xc) * sin(g))  + ((cubo[i].y - yc) * cos(g)) + yc;
        int z = cubo[i].z;

        if(i < 6)
            PaintBox1->Canvas->Pen->Color = clLime;
        else
            PaintBox1->Canvas->Pen->Color = clAqua;

        if(cubo[i].opcion)
            LineTo3D(x, y, z, Radianes(45.0),Radianes(30));
        else
            MoveTo3D(x, y, z, Radianes(45.0),Radianes(30));
    }
}

Si hay dudas con el código favor de comentar y con gusto explicare paso a paso.

8 comentarios:

  1. Hey amigo!

    Estoy empezando con c++ y em gustaria saber si puedes ayudarme a prender todo lo q encuentro aqui. Tmabien cree un sitio

    www.my3dmath.com

    mi correo es eduardo.mrqez@gmail.com

    Comunicate tengo un par de preguntras xD por no decir que bastantes.

    ResponderEliminar
    Respuestas
    1. Mas adelante pondré tutoriales basicos en c++ y tambien sobre el uso de OpenGl

      Eliminar
  2. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  3. disculpa buenos dias

    esta hecho en c#

    ResponderEliminar
  4. como lo corro en mi visual studio??

    ResponderEliminar
  5. Trate de ejecutar el programa que presentas en la página y no corre porque me pide #include , esto es, la cabecera vcl.h, me la podrías proporcionar ?

    ResponderEliminar