/*
* THIS PROGRAM DRAWS THE PERSPECTIVE PROJECTIONS OF A CUBOID AND ROTATES IT BY 60 DEGREES
*/
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<graphics.h>
#include<dos.h>
#include<math.h>
#define root_2 1.414
#define uxy 100
#define unitz 100
#define adjust 1/root_2
void drawAxis();
void drawCube(double[][4]);
void matrix_mult(double[][4],double[][4],double[][4]);
void convToOrdinaryCoordinate(double[][4]);
int sign(double);
void main(){
int gdriver=DETECT,gmode,ecode;
double f[8][4]; //matrix to hold cube vertices
f[0][0]= 0; f[0][1]= 0; f[0][2]= 1; f[0][3]=1; //A
f[1][0]= 1; f[1][1]= 0; f[1][2]= 1; f[1][3]=1; //B
f[2][0]= 1; f[2][1]= 1; f[2][2]= 1; f[2][3]=1; //C
f[3][0]= 0; f[3][1]= 1; f[3][2]= 1; f[3][3]=1; //D
f[4][0]= 0; f[4][1]= 0; f[4][2]= 0; f[4][3]=1; //E
f[5][0]= 1; f[5][1]= 0; f[5][2]= 0; f[5][3]=1; //F
f[6][0]= 1; f[6][1]= 1; f[6][2]= 0; f[6][3]=1; //G
f[7][0]= 0; f[7][1]= 1; f[7][2]= 0; f[7][3]=1; //H
initgraph(&gdriver,&gmode,"C:\\TC\\bgi");
ecode = graphresult();
if (ecode != grOk){ /* an error occurred */
printf("Graphics error: %s\n", grapherrormsg(ecode));
printf("Press any key to halt:");
getch();
exit(1); /* terminate with an error code */
}
float z;
printf("\nEnter the center of projection(on z-axis): ");
scanf("%f",&z);
double r = -1.0/z;
//perspection matrix
double Pr[4][4] = {1,0,0,0,
0,1,0,0,
0,0,0,r,
0,0,0,1};
//orthographic matrix, for z=0
double Po[4][4] = {1,0,0,0,
0,1,0,0,
0,0,0,0,
0,0,0,1};
clrscr();
drawAxis(); //render the axes
drawCube(f); //draw the untransformed cube
clrscr();
double Temp[8][4],Temp2[8][4];
matrix_mult(f,Pr,Temp);
convToOrdinaryCoordinate(Temp); //apply perspective
matrix_mult(Temp,Po,Temp2); //orthographic
convToOrdinaryCoordinate(Temp2);
clrscr();
drawAxis();
drawCube(Temp2); //draw the final projection
//Rotate by 60 degree about x-axis using following rotation matrix
double Prot[][4]={1,0,0,0,
0,cos(M_PI/3),sin(M_PI/3),0,
0,-sin(M_PI/3),cos(M_PI/3),0,
0,0,0,1};
//translation matrix
double Pt[][4] = { 1,0,0,0,
0,1,0,0,
0,0,1,0,
-0.5,-0.5,-0.5,1};
//reverse translation matrix
double Pt_rev[][4] = { 1,0,0,0,
0,1,0,0,
0,0,1,0,
0.5,0.5,0.5,1};
matrix_mult(f,Pt,Temp); //translate to origin
convToOrdinaryCoordinate(Temp);
matrix_mult(Temp,Prot,Temp2); //apply rotation
convToOrdinaryCoordinate(Temp2);
matrix_mult(Temp2,Pr,Temp); //apply perspective
convToOrdinaryCoordinate(Temp);
matrix_mult(Temp,Po,Temp2); //apply orthographic
convToOrdinaryCoordinate(Temp2);
matrix_mult(Temp2,Pt_rev,Temp); //translate back
convToOrdinaryCoordinate(Temp);
clrscr();
drawAxis();
drawCube(Temp);
closegraph();
}
void drawAxis(){
int ox,oy;
int z_length; //10 unit squares along z-axis
char c[10];
ox=getmaxx()/2;
oy=getmaxy()/2;
z_length=50*unitz;
cleardevice();
setcolor(BROWN);
line(0,oy,getmaxx(),oy); //x-axis
line(ox,0,ox,getmaxy()); //y-axis
line(ox+z_length/root_2,oy-z_length/root_2,ox-z_length/root_2,oy+z_length/root_2); //z-axis
}
void drawCube(double C[][4]) {
int v[10],sa,sb,sc,sd;
int ox=getmaxx()/2,oy=getmaxy()/2;
setlinestyle(SOLID_LINE,1,3);
sa=C[0][2]==0?0:sign(C[0][2]);
sb=C[1][2]==0?0:sign(C[1][2]);
sc=C[2][2]==0?0:sign(C[1][2]);
sd=C[3][2]==0?0:sign(C[1][2]);
v[0]=ox+uxy*(C[0][0]-adjust*sa);
v[1]=oy-uxy*(C[0][1]-adjust*sa);
v[2]=ox+uxy*(C[1][0]-adjust*sb);
v[3]=oy-uxy*(C[1][1]-adjust*sb);
v[4]=ox+uxy*(C[2][0]-adjust*sc);
v[5]=oy-uxy*(C[2][1]-adjust*sc);
v[6]=ox+uxy*(C[3][0]-adjust*sd);
v[7]=oy-uxy*(C[3][1]-adjust*sd);
v[8]=ox+uxy*(C[0][0]-adjust*sa);
v[9]=oy-uxy*(C[0][1]-adjust*sa);
setcolor(RED);
drawpoly(5,v);
getch();
v[0]=ox+uxy*C[4][0];
v[1]=oy-uxy*C[4][1];
v[2]=ox+uxy*C[5][0];
v[3]=oy-uxy*C[5][1];
v[4]=ox+uxy*C[6][0];
v[5]=oy-uxy*C[6][1];
v[6]=ox+uxy*C[7][0];
v[7]=oy-uxy*C[7][1];
v[8]=ox+uxy*C[4][0];
v[9]=oy-uxy*C[4][1];
setcolor(MAGENTA);
drawpoly(5,v);
getch();
setcolor(GREEN);
line(ox+uxy*(C[0][0]-adjust*sa),oy-uxy*(C[0][1]-adjust*sa),ox+uxy*C[4][0],oy-uxy*C[4][1]);
line(ox+uxy*(C[1][0]-adjust*sb),oy-uxy*(C[1][1]-adjust*sb),ox+uxy*C[5][0],oy-uxy*C[5][1]);
line(ox+uxy*(C[2][0]-adjust*sc),oy-uxy*(C[2][1]-adjust*sc),ox+uxy*C[6][0],oy-uxy*C[6][1]);
line(ox+uxy*(C[3][0]-adjust*sd),oy-uxy*(C[3][1]-adjust*sd),ox+uxy*C[7][0],oy-uxy*C[7][1]);
getch();
}
//matrix multiplication of 8X4 and 4X4 matrices
void matrix_mult(double A[][4],double B[][4],double C[][4]){
int k,i,j;
for(i=0;i<8;i++)
for(j=0;j<4;j++){
C[i][j] = 0;
for(k=0;k<4;k++)
C[i][j] = C[i][j] + A[i][k]*B[k][j];
}
}
void convToOrdinaryCoordinate(double M[][4]){
int i,j;
for(i=0;i<8;i++)
for(j=0;j<4;j++)
M[i][j] /= M[i][3];
}
int sign(double x){
if(x>0)
return 1;
else
return -1;
}
SAMPLE OUTPUT:
· Original cuboid & its perspective projection onto z=0 plane from a point on the Z axis (0,0,5) –
· Rotation by 60 degrees –
No comments:
Post a Comment
Do you think this information useful or was not up to the mark? Comment if you have any advices or suggestions about the post.