#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <dos.h>
#define Pi 3.1415926536
enum Action{move,draw};
struct Point3D
{
float x;
float y;
float z;
Action action;
};
// this function initializes graphics mode
// it will work only if you're using Borland C++ compiler & BGI drivers
// if you're using another compiler you should overwrite body of this function
void init_gr(void)
{
/* request autodetection */
int gdriver = DETECT, gmode, errorcode;
/* initialize graphics mode */
initgraph(&gdriver, &gmode, "");
/* read result of initialization */
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg
(errorcode
));
printf("Press any key to halt:");
getch();
exit(1); /* return with error code */
}
}
// this function shuts graphics mode down
// it will work only if you're using Borland C++ compiler & BGI drivers
// if you're using another compiler you should overwrite body of this function
void end_gr(void)
{
closegraph();
}
// this function moves CP to (x,y) position
// it will work only if you're using Borland C++ compiler & BGI drivers
// if you're using another compiler you should overwrite body of this function
void MoveTo(int x, int y)
{
moveto(x,y);
}
// this function draws a line to (x,y) position
// it will work only if you're using Borland C++ compiler & BGI drivers
// if you're using another compiler you should overwrite body of this function
void LineTo(int x, int y)
{
lineto(x,y);
}
void draw3Dobject(Point3D *object, int N, float rho, float theta,
float phi, float dist_to_screen, int xshift, int yshift)
{
int x,y;
float xe,ye,ze,costh,sinph,cosph,sinth,v11,v12,v13,v21,v22,v32,v33,v23,v43;
// calculating coefficients
costh=cos(theta);
sinth=sin(theta);
cosph=cos(phi);
sinph=sin(phi);
v11=-sinth; v12=-cosph*costh; v13=-sinph*costh;
v21=costh; v22=-cosph*sinth; v23=-sinph*sinth;
v32=sinph; v33=-cosph;
v43=rho;
for (int i=0;i<N;i++)
{
// calculating eye coordinates
xe=v11*(object+i)->x+v21*(object+i)->y;
ye=v12*(object+i)->x+v22*(object+i)->y+v32*(object+i)->z;
ze=v13*(object+i)->x+v23*(object+i)->y+v33*(object+i)->z+v43;
// calculating screen coordinates
x=dist_to_screen*xe/ze+xshift;
y=dist_to_screen*ye/ze+yshift;
// drawing
if((object+i)->action==move)
MoveTo(x,y);
else
LineTo(x,y);
}
}
void RotateX(Point3D *object, int n, float angle)
{
float cosa,sina,y,z;
cosa=cos(angle);
sina=sin(angle);
for(int i=0;i<n;i++)
{
y=(object+i)->y*cosa-(object+i)->z*sina;
z=(object+i)->y*sina+(object+i)->z*cosa;
(object+i)->y=y;
(object+i)->z=z;
}
}
void RotateY(Point3D *object, int n, float angle)
{
float cosa,sina,x,z;
cosa=cos(angle);
sina=sin(angle);
for(int i=0;i<n;i++)
{
x=(object+i)->x*cosa+(object+i)->z*sina;
z=-(object+i)->x*sina+(object+i)->z*cosa;
(object+i)->x=x;
(object+i)->z=z;
}
}
void RotateZ(Point3D *object, int n, float angle)
{
float cosa,sina,x,y;
cosa=cos(angle);
sina=sin(angle);
for(int i=0;i<n;i++)
{
x=(object+i)->x*cosa-(object+i)->y*sina;
y=(object+i)->x*sina+(object+i)->y*cosa;
(object+i)->x=x;
(object+i)->y=y;
}
}
int main(void)
{
Point3D thetr[]={{100,100,100,move},
{100,200,100,draw},
{200,100,100,draw},
{100,100,100,draw},
{100,100,200,draw},
{200,100,100,draw},
{100,100,200,move},
{100,200,100,draw}};
Point3D cube[]={{-50,-50,-50,move},
{-50,50,-50,draw},
{-50,50,50,draw},
{50,50,50,draw},
{50,50,-50,draw},
{50,-50,-50,draw},
{50,-50,50,draw},
{-50,-50,50,draw},
{-50,50,50,draw},
{-50,-50,50,move},
{-50,-50,-50,draw},
{50,-50,-50,draw},
{50,50,-50,move},
{-50,50,-50,draw},
{50,-50,50,move},
{50,50,50,draw}};
int N=sizeof(thetr)/sizeof(Point3D);
int M=sizeof(cube)/sizeof(Point3D);
float rho=1500,theta=Pi/4,phi=-3*Pi/4,dist_to_screen=700;
int xshift=300, yshift=150,xshift1=200,yshift1=200;
// initializing graphics mode
init_gr();
/* examples */
while (!kbhit())
{
RotateX(cube,M,Pi/24);
RotateY(cube,M,Pi/24);
RotateZ(cube,M,Pi/24);
RotateY(thetr,N,Pi/30);
setcolor(12);
draw3Dobject(thetr,N,rho,theta,phi,dist_to_screen,xshift,yshift);
draw3Dobject(cube,M,rho,theta,phi,dist_to_screen,xshift1,yshift1);
setcolor(0);
delay(35);
draw3Dobject(thetr,N,rho,theta,phi,dist_to_screen,xshift,yshift);
draw3Dobject(cube,M,rho,theta,phi,dist_to_screen,xshift1,yshift1);
}
/* clean up */
getch();
end_gr();
return 0;
}