![]() | The 3D Story Your guide to the third dimension. |
#include <conio.h>#include <math.h> #include "gfxman2.h" #define MAXPOLYS 12 #define DIST 256 #define MIDDLEX 160 #define MIDDLEY 100 struct point { double x,y,z; }; struct poly { point a,b,c,n; unsigned char colour; double v; }; point RotPoint(point i,point a); struct poly RotPoly(struct poly i,point a); point ProjPoint(point i); struct poly ProjPoly(struct poly i); struct poly CalcNormal(struct poly i); double GetAngle(point a,point b); double GetVAngle(point a,int &vis); void DrawPoly(int minx,int miny,int medx,int medy,int maxx,int maxy,unsigned char colour); void Swap(int &x,int &y); void main(void); void precalc(void); double c[3600],s[3600]; void main(void) { precalc(); int vis; struct poly p[]={{{25,-25,25},{-25,25,25},{-25,-25,25},{0,0,0},1} // Back ,{{-25,25,25},{25,-25,25},{25,25,25},{0,0,0},1} ,{{25,-25,-25},{-25,25,-25},{25,25,-25},{0,0,0},1} // Front ,{{-25,25,-25},{25,-25,-25},{-25,-25,-25},{0,0,0},1} ,{{25,25,-25},{25,-25,25},{25,-25,-25},{0,0,0},1} // Left ,{{25,-25,25},{25,25,-25},{25,25,25},{0,0,0},1} ,{{-25,-25,25},{-25,25,-25},{-25,-25,-25},{0,0,0},1} // Right ,{{-25,25,-25},{-25,-25,25},{-25,25,25},{0,0,0},1} ,{{-25,25,25},{25,25,-25},{-25,25,-25},{0,0,0},1} // Top ,{{25,25,-25},{-25,25,25},{25,25,25},{0,0,0},1} ,{{25,-25,-25},{-25,-25,25},{-25,-25,-25},{0,0,0},1} // Bottom ,{{-25,-25,25},{25,-25,-25},{25,-25,25},{0,0,0},1} /*,{{,,},{,,},{,,},{,,},}*/ }; struct poly rp[MAXPOLYS]; int depth[MAXPOLYS],vp; point angle={10,0,20}; int a,b; for(a=0;a<MAXPOLYS;a++) p[a]=CalcNormal(p[a]); SetVGA(); do { for(a=0;a<MAXPOLYS;a++) rp[a]=ProjPoly(p[a]=RotPoly(p[a],angle)); vp=0; for(a=0;a<MAXPOLYS;a++) { rp[a].v=GetVAngle(rp[a].n,vis); if(vis) depth[vp++]=a; } for(a=vp-1;a>=0;a--) for(b=0;b<a;b++) if(rp[depth[a]].a.z>rp[depth[b]].a.z) Swap(depth[a],depth[b]); Cls(); for(a=0;a<vp;a++) { DrawPoly(rp[depth[a]].a.x,rp[depth[a]].a.y, rp[depth[a]].b.x,rp[depth[a]].b.y, rp[depth[a]].c.x,rp[depth[a]].c.y, (p[depth[a]].colour<<4)-rp[depth[a]].v*15); } WaitRetrace(); ScreenCopy(); } while(!kbhit()); getch(); SetText(); } struct poly RotPoly(struct poly i,point a) { struct poly r; r.colour=i.colour; r.a=RotPoint(i.a,a); r.b=RotPoint(i.b,a); r.c=RotPoint(i.c,a); r.n=RotPoint(i.n,a); return r; } point RotPoint(point i,point a) { point r; r.x=c[(int)a.z]*i.x-s[(int)a.z]*i.y; r.y=s[(int)a.z]*i.x+c[(int)a.z]*i.y; r.z=i.z; i.x=c[(int)a.y]*r.x-s[(int)a.y]*r.z; i.y=r.y; i.z=s[(int)a.y]*r.x+c[(int)a.y]*r.z; r.x=i.x; r.y=s[(int)a.x]*i.z+c[(int)a.x]*i.y; r.z=c[(int)a.x]*i.z-s[(int)a.x]*i.y; return r; } struct poly ProjPoly(struct poly i) { struct poly r; r.n=i.n; r.colour=i.colour; r.a=ProjPoint(i.a); r.b=ProjPoint(i.b); r.c=ProjPoint(i.c); if(r.b.z>r.a.z) r.a.z=r.b.z; if(r.c.z>r.a.z) r.a.z=r.c.z; return r; } point ProjPoint(point i) { double t; point r; t=DIST+i.z; r.z=i.z; if(t) { r.x=i.x*DIST/t+MIDDLEX; r.y=i.y*DIST/t+MIDDLEY; } else { r.x=i.x+MIDDLEX; r.y=i.y+MIDDLEY; } return r; } void DrawPoly(int minx,int miny,int medx,int medy,int maxx,int maxy,unsigned char colour) { if(medy>maxy) { Swap(maxy,medy); Swap(maxx,medx); } if(miny>medy) { Swap(miny,medy); Swap(minx,medx); } if(medy>maxy) { Swap(medy,maxy); Swap(medx,maxx); } int lx,sx; float temp; for(int y=miny;y<=maxy;y++) { temp=(maxy-miny); temp=(temp==0)?1:temp; lx=minx+((maxx-minx)/temp)*(y-miny); if(y<medy) { temp=(medy-miny); temp=(temp==0)?1:temp; sx=minx+((medx-minx)/temp)*(y-miny); } else { temp=(maxy-medy); temp=(temp==0)?1:temp; sx=medx+((maxx-medx)/temp)*(y-medy); } Line(lx,y,sx,y,colour); } } void Swap(int &x,int &y) { int temp=x; x=y; y=temp; } struct poly CalcNormal(struct poly i) { double ax,ay,az,bx,by,bz; struct poly r=i; ax=i.a.x-i.c.x; ay=i.a.y-i.c.y; az=i.a.z-i.c.z; bx=i.b.x-i.c.x; by=i.b.y-i.c.y; bz=i.b.z-i.c.z; r.n.x=ay*bz-az*by; r.n.y=bx*az-ax*bz; r.n.z=ax*by-bx*ay; return r; }