#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
{
int x;
int y;
int 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);
}
}
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}};
int N=sizeof(thetr)/sizeof(Point3D);
float rho=700,theta=Pi/4,phi=Pi/4,dist_to_screen=300;
int xshift=300, yshift=150;
// initializing graphics mode
init_gr();
/* examples */
while (!kbhit())
{
theta+=0.05;
// rotating viewpoint
if (phi>2*Pi) phi-=2*Pi;
setcolor(11);
draw3Dobject(thetr,N,rho,theta,phi,dist_to_screen,xshift,yshift);
setcolor(0);
delay(15);
draw3Dobject(thetr,N,rho,theta,phi,dist_to_screen,xshift,yshift);
}
/* clean up */
getch();
end_gr();
return 0;
}