Sunday, January 8, 2017

Car Viewer in TurboC++

This project was created  several years back when I was not good at programming. I was a learner then. I knew very little of graphics. Yet I tried to rotate and do coordinate transformations. This project does viewing... For theory behind this refer James D Foley "Computer Graphics"

Snapshot:


It was supposed to be a car but without wheels.
I am pasting the source here itself for online viewing.

#include<stdio.h>
#include<graphics.h>
#include<conio.h>
#include<math.h>
#include<dos.h>
#include<stdlib.h>

typedef struct
{float x,y,z;
}point;

typedef struct
{float dx,dy,dz;
}vector;

typedef struct
{int v1,v2; //two vertices of an edge (index into vertices)
}edge;

/*typedef struct
{int e1,e2,e3,e4;     //index into edges
}polygon;
*/
point vertices[40];
edge edges[50];
//polygon polymesh[20];

int noofpolygons,noofedges,noofvertices;
float cosx,sinx,cosy,siny,cosz,sinz,d,umin,umax,vmin,vmax;
float shxpar,shypar,sperx,spery,sperz,f,b;
point vrp,prp,cube[8];
vector vpn,vup={0,1,0},dop;

point transform( point p)
{
 float x,y,z;

  p.x=p.x-vrp.x;        //translate by t(-vrp)
  p.y=p.y-vrp.y;
  p.z=p.z-vrp.z;

  x=p.x;                // rotate wrt y
  p.x=p.x*cosy+p.z*siny;
  p.z=-x*siny+p.z*cosy;

  y=p.y;               // rotate wrt x
  p.y=p.y*cosx-p.z*sinx;
  p.z=y*sinx+p.z*cosx;

  x=p.x;              // rotate wrt z
  p.x=p.x*cosz-p.y*sinz;
  p.y=x*sinz+p.y*cosz;

  p.x=p.x-prp.x;         // translate by t(-prp)
  p.y=p.y-prp.y;
  p.z=p.z-prp.z;

/*  p.x=p.x+shxpar*p.z;     //shear such that dop is z axis
  p.y=p.y+shypar*p.z;

  p.x*=sperx;            // scale such that the size of view
  p.y*=spery; // volume is canonical view volume
  p.z*=sperz;           */

  p.x*=(d/p.z);           // project onto proj n plane
  p.y*=(d/p.z);
  p.z=d;

  return(p);
}
void findmcomp()
{float d1,d2,d3,x,y,z;
     // rotate wrt y
 d=prp.z;
 d1=sqrt(vpn.dx*vpn.dx+vpn.dz*vpn.dz);
 cosy=vpn.dz/d1;
 siny=vpn.dx/d1;

 vpn.dx=0;
 vpn.dz=d1;

 x=vup.dx;
 vup.dx=vup.dx*cosy+vup.dz*siny;
 vup.dz=-x*siny+vup.dz*cosy;
 // rotate wrt x
 d2=sqrt(vpn.dx*vpn.dx+vpn.dy*vpn.dy+vpn.dz*vpn.dz);

 cosx=d1/d2;
 sinx=vpn.dy/d2;

 vpn.dy=0;
 vpn.dz=d2;

 y=vup.dy;
 vup.dy=vup.dy*cosx-vup.dz*sinx;
 vup.dz=y*sinx+vup.dz*cosx;   // this will be zero;
   // rotate wrt z
 d3=sqrt(vup.dx*vup.dx+vup.dy*vup.dy);

 cosz=1;//vup.dy/d3;
 sinz=0;//vup.dx/d3;

 vup.dx=0;
 vup.dy=d3;

/* dop.dx=(umax-umin)/2-prp.x;
 dop.dy=(vmax-vmin)/2-prp.y;
 dop.dz=-prp.z;

 shxpar=-dop.dx/dop.dz;
 shypar=-dop.dy/dop.dz;

 sperx=-2*prp.z/((umax-umin)*(-prp.z+b));
 spery=-2*prp.z/((vmax-vmin)*(-prp.z+b));
 sperz=-1/(-prp.z+b);     */
}
void initializevertices()
{
/* car */
vertices[0].x=10;vertices[0].y=0;vertices[0].z=10;    //0
vertices[1].x=50;vertices[1].y=0;vertices[1].z=10;    //1
vertices[2].x=50;vertices[2].y=30;vertices[2].z=15;  //2
vertices[3].x=10;vertices[3].y=30;vertices[3].z=15;  //3
vertices[4].x=10;vertices[4].y=40;vertices[4].z=50;  //4
vertices[5].x=50;vertices[5].y=40;vertices[5].z=50;   //5
vertices[6].x=50;vertices[6].y=70;vertices[6].z=55;       //6
vertices[7].x=10;vertices[7].y=70;vertices[7].z=55;      //7
vertices[8].x=10;vertices[8].y=70;vertices[8].z=95;     //8
vertices[9].x=50;vertices[9].y=70;vertices[9].z=95;     //9
vertices[10].x=50;vertices[10].y=40;vertices[10].z=100;    //10
vertices[11].x=10;vertices[11].y=40;vertices[11].z=100;    //11
vertices[12].x=10;vertices[12].y=30;vertices[12].z=135;    //12
vertices[13].x=50;vertices[13].y=30;vertices[13].z=135;   //13
vertices[14].x=50;vertices[14].y=0;vertices[14].z=140;   //14
vertices[15].x=10;vertices[15].y=0;vertices[15].z=140;   //15
vertices[16].x=10;vertices[16].y=0;vertices[16].z=100;   //16
vertices[17].x=50;vertices[17].y=0;vertices[17].z=100; // 17
vertices[18].x=50;vertices[18].y=0;vertices[18].z=95;  //18
vertices[19].x=10;vertices[19].y=0;vertices[19].z=95;  //19
vertices[20].x=10;vertices[20].y=0;vertices[20].z=55;  //20
vertices[21].x=50;vertices[21].y=0;vertices[21].z=55; //21
vertices[22].x=50;vertices[22].y=0;vertices[22].z=50; //22
vertices[23].x=10;vertices[23].y=0;vertices[23].z=50;  //23
vertices[24].x=50;vertices[24].y=40;vertices[24].z=30;  //24
vertices[25].x=10;vertices[25].y=40;vertices[25].z=30;  //25
vertices[26].x=50;vertices[26].y=40;vertices[26].z=115;  //26
vertices[27].x=10;vertices[27].y=40;vertices[27].z=115;  //27
}
void initializeedges()
{
 /* car */
 edges[0].v1=0;edges[0].v2=1;    //1
 edges[1].v1=1;edges[1].v2=2;   //2
 edges[2].v1=2;edges[2].v2=3;  //3
 edges[3].v1=3;edges[3].v2=0;   //4
 edges[4].v1=3;edges[4].v2=25;  //5
 edges[5].v1=4;edges[5].v2=5;  //6
 edges[6].v1=5;edges[6].v2=6;  //7
 edges[7].v1=6;edges[7].v2=7;  //8
 edges[8].v1=7;edges[8].v2=4;  //9
 edges[9].v1=7;edges[9].v2=8;  //10
 edges[10].v1=8;edges[10].v2=9;  //11
 edges[11].v1=9;edges[11].v2=10;  //12
 edges[12].v1=10;edges[12].v2=11;  //13
 edges[13].v1=11;edges[13].v2=8;  //14
 edges[14].v1=9;edges[14].v2=6;  //15
 edges[15].v1=27;edges[15].v2=11;  //16
 edges[16].v1=12;edges[16].v2=13;  //17
 edges[17].v1=10;edges[17].v2=26;  //18
 edges[18].v1=13;edges[18].v2=14;  //19
 edges[19].v1=14;edges[19].v2=15;  //20
 edges[20].v1=15;edges[20].v2=12;  //21
 edges[21].v1=15;edges[21].v2=16;  //22
 edges[22].v1=16;edges[22].v2=17;  //23
 edges[23].v1=17;edges[23].v2=14;  //24
 edges[24].v1=18;edges[24].v2=19;  //25
 edges[25].v1=19;edges[25].v2=20;  //26
 edges[26].v1=20;edges[26].v2=21;  //27
 edges[27].v1=21;edges[27].v2=18;  //28
 edges[28].v1=22;edges[28].v2=23;  //29
 edges[29].v1=23;edges[29].v2=0;   //30
 edges[30].v1=22;edges[30].v2=1;   //31
 edges[31].v1=24;edges[31].v2=2;  //32
  edges[32].v1=24;edges[32].v2=25;  //33
   edges[33].v1=25;edges[33].v2=4;  //34
    edges[34].v1=24;edges[34].v2=5;  //35
     edges[35].v1=26;edges[35].v2=27;  //36
      edges[36].v1=27;edges[36].v2=12;  //37
       edges[37].v1=26;edges[37].v2=13;  //38
       edges[38].v1=5;edges[38].v2=22;  //38
       edges[39].v1=4;edges[39].v2=23;  //38
       edges[40].v1=10;edges[40].v2=17;  //38
       edges[41].v1=11;edges[41].v2=16;  //38
       edges[42].v1=5;edges[42].v2=10;  //38
       edges[43].v1=4;edges[43].v2=11;  //38
}
void initializepolymesh()
{

}
void initializeobjects()
{
  initializevertices();
  initializeedges();
  initializepolymesh();
}
void display()
{
  for(int i=0;i<44;i++)
  line(vertices[edges[i].v1].x+320,240+vertices[edges[i].v1].y,vertices[edges[i].v2].x+320,240+vertices[edges[i].v2].y);
}
void findvrpprpvpn(float theta)
{ float rtheta1,rtheta2,lvpn;

   rtheta1=theta*3.141/180;
   rtheta2=(theta+180)*3.141/180;
   vrp.x=20*cos(rtheta1)+30;
   vrp.z=20*sin(rtheta1)+75;
   vrp.y=120;

   prp.x=50*cos(rtheta2)+30;
   prp.z=50*sin(rtheta2)+30;
   prp.y=130;

   vpn.dx=vrp.x-prp.x;
   vpn.dy=vrp.y-prp.y;
   vpn.dz=vrp.z-prp.z;

   lvpn=sqrt(vpn.dx*vpn.dx+vpn.dy*vpn.dy+vpn.dz*vpn.dz);
   vpn.dx=vpn.dx/lvpn;
   vpn.dy=vpn.dy/lvpn;
   vpn.dz=vpn.dz/lvpn;
//   putpixel(prp.x+320,240-prp.z,WHITE);
   prp.x=0;
   prp.y=0;
   prp.z=120;
}
void main()
{
 int gd=DETECT,gm;
 float theta;
 char text[10];
 initgraph(&gd,&gm,"c:\\tc\\bgi");
 moveto(0,0);
  theta=0;
  while(!kbhit())
  {findvrpprpvpn(theta);
   findmcomp();
   initializeobjects();
   for(int i=0;i<32;i++)
    vertices[i]=transform(vertices[i]);
   delay(50);
   cleardevice();
   display();
    theta+=0.1;
    if(theta>360) theta=0;
   }
  getch();
  closegraph();
}

Very soon I will modify the code to perform 3D viewing from any arbitrary position. Currently I am assuming many things. Will post the modified code soon. Several bugs in the software... got confused with x,y and z axis.

No comments:

Post a Comment