#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)
{
const int n=4; // number of cubes segments +1
Point3D cube[15*n]; // coordinates for cubes points
float rho=1900,theta=Pi/3,phi=2*Pi/3,dist_to_screen=600; // view point
int xshift=300, yshift=140; // picture offset
float side=300; // cubes parameters
float delta;// auxulary variable
// initializing graphics mode
init_gr();
// generating cube
delta=side/(n-1);
for (int i=0;i<n;i++)
{
for(int j=i*5;j<i*5+5;j++)
{
cube[j].x=i*delta;
cube[j].action=draw;
}
cube[i*5].y=0;
cube[i*5].z=0;
cube[i*5].action=move;
cube[i*5+1].y=side;
cube[i*5+1].z=0;
cube[i*5+2].y=side;
cube[i*5+2].z=side;
cube[i*5+3].y=0;
cube[i*5+3].z=side;
cube[i*5+4].y=0;
cube[i*5+4].z=0;
}
int c=5*n;
for (i=0;i<n;i++)
{
for(int j=i*5;j<i*5+5;j++)
{
cube[c+j].y=i*delta;
cube[c+j].action=draw;
}
cube[c+i*5].x=0;
cube[c+i*5].z=0;
cube[c+i*5].action=move;
cube[c+i*5+1].x=side;
cube[c+i*5+1].z=0;
cube[c+i*5+2].x=side;
cube[c+i*5+2].z=side;
cube[c+i*5+3].x=0;
cube[c+i*5+3].z=side;
cube[c+i*5+4].x=0;
cube[c+i*5+4].z=0;
}
c=10*n;
for (i=0;i<n;i++)
{
for(int j=i*5;j<i*5+5;j++)
{
cube[c+j].z=i*delta;
cube[c+j].action=draw;
}
cube[c+i*5].y=0;
cube[c+i*5].x=0;
cube[c+i*5].action=move;
cube[c+i*5+1].y=side;
cube[c+i*5+1].x=0;
cube[c+i*5+2].y=side;
cube[c+i*5+2].x=side;
cube[c+i*5+3].y=0;
cube[c+i*5+3].x=side;
cube[c+i*5+4].y=0;
cube[c+i*5+4].x=0;
}
// drawing
draw3Dobject(cube,15*n,rho,theta,phi,dist_to_screen,xshift,yshift);
/* clean up */
getch();
end_gr();
return 0;
}