DIBUJO ASISTIDO POR ORDENADOR
LISTADO 7

Este programa ha sido creado con el compilador Borland C/C++ 3.1, utilizando el modelo LARGE de memoria.
Su funcionamiento se puede comprobar con alguno de estos objetos 3D.


   #include <graphics.h>
   #include <stdlib.h>
   #include <stdio.h>
   #include <string.h>
   #include <conio.h>
   #include <alloc.h>
   #include <math.h>
   
   typedef struct {
      int nv, *v;
      float z;
   } ELEM;
   
   float matt[4][4], matr[4][4], matp[4][4];
   
   void mmat (float a[4][4], float b[4][4])
   {
      int i, j, k;
      float c[4][4];
      for (i=0;i<4;i++)
      for (j=0;j<4;j++) {
         c[i][j]=0.;
         for (k=0;k<4;k++)
            c[i][j] +=a[i][k]*b[k][j];
      }
      for (i=0;i<4;i++)
      for (j=0;j<4;j++)
         b[i][j]=c[i][j];
   }
   
   void proyecta (float p[4], float q[4])
   {
      int i, j;
      for (i=0;i<4;i++) {
         q[i]=0.;
         for (j=0;j<4;j++)
            q[i] +=p[j] * matp[j][i];
      }
      for (i=0;i<3;i++)
         q[i] /= q[3];
   }
   
   void rota (char eje, float a)
   {
      float ang=a * M_PI / 180.;
      if (eje=='X') {
         matr[0][0]=1; matr[0][1]=0; matr[0][2]=0; matr[0][3]=0;
         matr[1][0]=0; matr[1][1]=cos(ang); matr[1][2]=sin(ang); matr[1][3]=0;
         matr[2][0]=0; matr[2][1]=-sin(ang); matr[2][2]=cos(ang); matr[2][3]=0;
         matr[3][0]=0; matr[3][1]=0; matr[3][2]=0; matr[3][3]=1;
      }
      if (eje=='Y') {
         matr[0][0]=cos(ang); matr[0][1]=0; matr[0][2]=-sin(ang); matr[0][3]=0;
         matr[1][0]=0; matr[1][1]=1; matr[1][2]=0; matr[1][3]=0;
         matr[2][0]=sin(ang); matr[2][1]=0; matr[2][2]=cos(ang); matr[2][3]=0;
         matr[3][0]=0; matr[3][1]=0; matr[3][2]=0; matr[3][3]=1;
      }
      if (eje=='Z') {
         matr[0][0]=cos(ang); matr[0][1]=sin(ang); matr[0][2]=0; matr[0][3]=0;
         matr[1][0]=-sin(ang); matr[1][1]=cos(ang); matr[1][2]=0; matr[1][3]=0;
         matr[2][0]=0; matr[2][1]=0; matr[2][2]=1; matr[2][3]=0;
         matr[3][0]=0; matr[3][1]=0; matr[3][2]=0; matr[3][3]=1;
      }
   }
   
   int main(int argc, char *argv[])
   {
      int gdriver=DETECT, gmode, errorcode;
      int i, j, k, ni, nj, nf, np, ne, nv, pol[128], *id;
      char *pv, linea[256];
      FILE *fi;
      ELEM *el, *ve;
      float *x, *y, *z, p[4], q[4];
      float xmin, xmax, ymin, ymax, zmin, zmax, xc, yc, zc;
      float e, xm, ym, angx, angy, angz, *xp, *yp, *zp;
   
      if (argc !=2) {
         fprintf(stderr, "uso: obj fich.geo\n");
         exit(1);
      }
   
      matp[0][0]=1; matp[0][1]=0; matp[0][2]=0; matp[0][3]=0;
      matp[1][0]=0; matp[1][1]=1; matp[1][2]=0; matp[1][3]=0;
      matp[2][0]=0; matp[2][1]=0; matp[2][2]=1; matp[2][3]=0;
      matp[3][0]=0; matp[3][1]=0; matp[3][2]=0; matp[3][3]=1;
   
      if ((fi=fopen(argv[1], "r"))==NULL) {
         fprintf(stderr, "error: no puedo abrir %s\n", argv[1]);
         exit(2);
      }
   
      fscanf(fi, "%d %d %d", &np, &ne, &nv);
      clrscr();
   
      printf("Ang X: "); scanf("%f", &angx);
      printf("Ang Y: "); scanf("%f", &angy);
      printf("Ang Z: "); scanf("%f", &angz);
   
      /* coordenadas originales */
      x=(float *) calloc (np, sizeof (float));
      y=(float *) calloc (np, sizeof (float));
      z=(float *) calloc (np, sizeof (float));
   
      /* coordenadas proyectadas */
      xp=(float *) calloc (np, sizeof (float));
      yp=(float *) calloc (np, sizeof (float));
      zp=(float *) calloc (np, sizeof (float));
   
      /* vector de elementos */
      ve=(ELEM *) calloc (ne, sizeof (ELEM));
      id=(int *) calloc(ne, sizeof (int));
   
      rota('X', angx); mmat(matr, matp);
      rota('Y', angy); mmat(matr, matp);
      rota('Z', angz); mmat(matr, matp);
   
      xmin = ymin = zmin = 999999.;
      xmax = ymax = zmax = -xmin;
   
      for (i=0;i<np;i++) {
         fscanf (fi, "%f%f%f\n", &x[i], &y[i], &z[i]);
   
         p[0]=x[i]; p[1]=y[i]; p[2]=z[i]; p[3]=1.;
         proyecta (p, q);
         xp[i]=q[0]; yp[i]=q[1]; zp[i]=q[2];
   
         xmin = min(xmin, xp[i]);
         xmax = max(xmax, xp[i]);
         ymin = min(ymin, yp[i]);
   
         ymax = max(ymax, yp[i]);
         zmin = min(zmin, zp[i]);
         zmax = max(zmax, zp[i]);
      }
      xc = 0.5 * (xmin+xmax);
      yc = 0.5 * (ymin+ymax);
      zc = 0.5 * (zmin+zmax);
   
      /* initialize graphics and local variables */
      initgraph(&gdriver, &gmode, "");
   
      /* read result of initialization */
      errorcode=graphresult();
      /* an error occurred */
      if (errorcode !=grOk) {
         printf("Graphics error: %s\n", grapherrormsg(errorcode));
         printf("Press any key to halt:");
         getch();
         exit(1);
      }

      setcolor(getmaxcolor());
      xm = 0.5 * (getmaxx() + 1);
      ym = 0.5 * (getmaxy() + 1);
      e = 1.5 * min(xm/(xmax-xmin), ym/(ymax-ymin));
   
      for (i=0;i<ne;i++) {
         fgets(linea, 256, fi);
         pv=strtok(linea, " ");
         sscanf(pv, "%d", &nv);
         ve[i].nv = nv;
         id[i]=i;
         ve[i].v = (int *) calloc (nv, sizeof (int));
         for (j=0;j<nv;j++) {
            pv=strtok(NULL, " ");
            sscanf(pv, "%d", &ni); ni--;
            ve[i].v[j] = ni;
         }
      }
      fclose(fi);
   
      for (i=0;i<ne;i++) {
         el = &ve[i];
         ni = el->v[0];
         el->z = zp[ni];
         for (j=1;j<el->nv;j++) {
            nj = el->v[j];
            line (xm + (xp[ni]-xc)*e, ym - (yp[ni]-yc)*e,
               xm + (xp[nj]-xc)*e, ym - (yp[nj]-yc)*e);
            ni = nj;
            el->z += zp[ni];
         }
         el->z /= el->nv;
         nj = el->v[0];
         line (xm + (xp[ni]-xc)*e, ym - (yp[ni]-yc)*e,
            xm + (xp[nj]-xc)*e, ym - (yp[nj]-yc)*e);
      }
   
      getch();
   
      for (i=0;i<ne;i++)
      for (j=i;j<ne;j++)
         if (ve[id[i]].z > ve[id[j]].z) {
            k = id[i];
            id[i] = id[j];
            id[j] = k;
         }
   
      for (i=0;i<ne;i++) {
         el = &ve[id[i]];
         for (j=0, k=0;j<el->nv;j++) {
            ni = el->v[j];
            pol[k++] = xm + (xp[ni]-xc)*e;
            pol[k++] = ym - (yp[ni]-yc)*e;
         }
         setfillstyle (SOLID_FILL, getbkcolor());
         fillpoly(el->nv, pol);
      }
      getch(); /* clean up */
      closegraph();
      return 0;
   }

Índice


© 1996-99, euitmt WWW team
Última modificación: 9 de Julio de 1999 - 13:38:33