Category : C Source Code
Archive   : CADSRC.ZIP
Filename : T-11.C

 
Output of file : T-11.C contained in archive : CADSRC.ZIP
/*__________________________________________________________________

t-11.c

FUNCTION: Draws a computer-shaded 3D sphere using the plane equation
method of hidden surface removal and the surface normal
method of halftone shading.

Compatibility: Supports VGA/EGA graphics adapters and monitors.

NOTE: You need the *.BGI files that come with Turbo-C in the same
directory (or on your PATH) as your executable or else
your EXE file won't run But it will complain that you must
use initgraph !! One of the Great error messages.
___________________________________________________________________

INCLUDE FILES */

#include
#include
#include
#include
#include

/*________________________________________________________________
DECLARATIONS */

float x=0.0,y=0.0,z=0.0;
float x1=0.0,x2=0.0,x3=0.0,x4=0.0;
float y1=0.0,y2=0.0,y3=0.0,y4=0.0;
float z1=0.0,z2=0.0,z3=0.0,z4=0.0;
float sx1=0.0,sx2=0.0,sx3=0.0,sx4=0.0,sx5=0.0;
float sy1=0.0,sy2=0.0,sy3=0.0,sy4=0.0,sy5=0.0;
float sx=0.0,sy=0.0;
float xa=0.0,ya=0.0,za=0.0;
float d=1200.0;

double r1=6.19592;
double r2=0.523590;
double r3=5.39778;
double sr1=0,sr2=0,sr3=0;
double cr1=0,cr2=0,cr3=0;
float mx=0,my=0.0,mz=-150.0;
int maxx=639,minx=0,maxy=199,miny=0;
float screen_x=639,screen_y=199;
float rx=0,ry=0;

int t=0,t1=0,t2=0, p1=0;
int C0=0,C1=1,C2=2,C3=3,C4=4,C5=5,C6=6,C7=7,C8=8,C9=9,C10=10,
C11=11,C12=12,C13=13,C14=14,C15=15,mode_flag=0;
int key_matte_clr=6, edge_clr=7, solid_clr=0;
float x_res,y_res;
float sp=0.0;
float sp1=0.0,sp2=0.0, sp3=0.0;
float xlarge=0.0,xsmall=0.0;
float ylarge=0.0,ysmall=0.0;
float zlarge=0.0,zsmall=0.0;
float x6=0.0,x7=0.0,y6=0.0,y7=0.0,z6=0.0,z7=0.0;

int NORM_HUE=0, BASE_CLR=0, CC4=0,CC5=0;
unsigned short CC6=0xffff;

/*********
next line that was in book gave "redcl'd variable"
compiler error so replaced "l" with "s"
and did same in illumination function.
He probably used a small L (looked like a 1 to me).
********/
float xs=0,ys=0,zs=1;

float v4=0.0;
int v5=0,v6=11,v7=0;
float xu=0.0,yu=0.0,zu=0.0;
float xn=0.0,yn=0.0,zn=0.0;
float xv=0.0,yv=0.0,zv=0.0;
float v1=0.0,v2=0.0,v3=0.0;
float xw=0.0,yw=0.0,zw=0.0;

char fill_0[]={0,0,0,0,0,0,0,0};
char fill_3[]={0,32,0,0,0,2,0,0};
char fill_6[]={32,0,2,0,128,0,8,0};
char fill_12[]={32,2,128,8,32,2,128,8};
char fill_25[]={68,17,68,17,68,17,68,17};
char fill_37[]={146,41,148,73,164,73,146,73};
char fill_50[]={85,170,85,170,85,170,85,170};
char fill_62[]={109,214,107,182,91,182,109,182};
char fill_75[]={187,238,187,238,187,238,187,238};
char fill_87[]={223,253,127,247,223,253,127,247};
char fill_93[]={255,223,255,255,255,253,255,255};
char fill_100[]={255,255,255,255,255,255,255,255};

int q=0,q1=0,q2=0;
double r4=6.28319,r5=6.28319;
float B11[36][3];
float B12[36][3];
float B21[36][2];
float B22[36][2];
double sr4=0.0,cr4=0.0,sr5=0.0,cr5=0.0;

void keyboard(void);void quit_pgm(void);void calc_3d(void);
void rotation(void); void window(void); void graphics_setup(void);
void coords(void);void draw_poly(void);void notice(int x, int y);
void visibility_test(void);void polycenter(void);
void illumination(void);void dither(void);void shade(void);
void values(void);

void sphere_coords(void); void draw_4poly(void);
void draw_3polynorth(void);void draw_3polysouth(void);
void upper_coords(void); void lower_coords(void);

/*___________________________________________________________

MAIN ROUTINE */

main()
{
graphics_setup();

setviewport(0,0,maxx,maxy,1);
key_matte_clr=C6;edge_clr=C7;solid_clr=C0, NORM_HUE=C1;

rotation();

r5=0.0;r4=0.0;x=30;sphere_coords();calc_3d(); window();
B11[0][0]=x;B11[0][1]=y;B11[0][2]=z;
B21[0][0]=sx;B21[0][1]=sy;
x=30;r5=0.17453;r4=0.0;lower_coords();
for (q1=0;q1<=35;q1++)
{
q2=q1+1; if (q2>35) q2=0;
draw_3polynorth();
keyboard();
}
r5=0.17453;
for (t2=1;t2<=16;t2++)
{
x=30;r4=0.0;upper_coords();
x=30;r5=r5+0.17453;r4=0.0;lower_coords();
for (q1=0;q1<=35;q1++)
{
q2=q1+1; if (q2>35) q2=0;
draw_4poly();
keyboard();
}
}
r5=3.14159;r4=0.0;x=30;sphere_coords();calc_3d();window();
B11[0][0]=x;B11[0][1]=y;B11[0][2]=z;
B21[0][0]=sx;B21[0][1]=sy;
x=30;r5=2.96706;r4=0.0;upper_coords();
for (q1=0;q1<=35;q1++)
{
q2=q1+1; if (q2>35) q2=0;
draw_3polysouth();
keyboard();
}
setcolor(C7);notice(0,0);
for (t1=1;t1!=2; ) keyboard();

quit_pgm();
}

/*_________________________________________________________________

FUNCTION: calculate and store coords for belt
*/
void upper_coords(void)
{
for (t=0;t<=35;t++)
{
x=30;sphere_coords();calc_3d();window();
B11[t][0]=x;B11[t][1]=y;B11[t][2]=z;
B21[t][0]=sx;B21[t][1]=sy;
r4=r4+0.17453;
keyboard();
}
return;
}

void lower_coords(void)
{
for (t=0;t<=35;t++)
{
x=30;sphere_coords();calc_3d();window();
B12[t][0]=x;B12[t][1]=y;B12[t][2]=z;
B22[t][0]=sx;B22[t][1]=sy;
r4=r4+0.17453;
keyboard();
}
return;
}

/*_________________________________________________________________

FUNCTION: calculate world coordinates for sphere
*/
void sphere_coords(void)
{
sr4=sin(r4);cr4=cos(r4);sr5=sin(r5);
cr5=cos(r5);x1=sr5*x;y=cr5*x;x=cr4*x1;z=sr4*x1;
return;
}

/*_________________________________________________________________

FUNCTION: draw 4-sided polygonal surface on sphere.
*/
void draw_4poly(void)
{
x1=B11[q1][0];y1=B11[q1][1];z1=B11[q1][2];
x2=B11[q2][0];y2=B11[q2][1];z2=B11[q2][2];
x3=B12[q2][0];y3=B12[q2][1];z3=B12[q2][2];
x4=B12[q1][0];y4=B12[q1][1];z4=B12[q1][2];
visibility_test(); if (sp>-100) return;
sx1=B21[q1][0];sy1=B21[q1][1];
sx2=B21[q2][0];sy2=B21[q2][1];
sx3=B22[q2][0];sy3=B22[q2][1];
sx4=B22[q1][0];sy4=B22[q1][1];
polycenter();
draw_poly();
illumination();shade();dither();
return;
}

/*_________________________________________________________________

FUNCTION: draw 3-sided polygonal surface on sphere.
*/
void draw_3polynorth(void)
{
x1=B12[q2][0];y1=B12[q2][1];z1=B12[q2][2];
x2=B12[q1][0];y2=B12[q1][1];z2=B12[q1][2];
x3=B11[0][0];y3=B11[0][1];z3=B11[0][2];
visibility_test(); if (sp>0) return;
sx1=B22[q2][0];sy1=B22[q2][1];
sx2=B22[q1][0];sy2=B22[q1][1];
sx3=B21[0][0];sy3=B21[0][1];
sx4=sx1;sy4=sy1;
x4=x1+0.5*(x2-x1);y4=y1+0.5*(y2-y1);z4=z1+0.5*(z2-z1);
x=x3+0.85*(x4-x3);y=y3+0.85*(y4-y3);z=z3+0.85*(z4-z3);
sx=d*x/z;sy=d*y/z;window();sx5=sx;sy5=sy;
draw_poly();
illumination();shade();dither();

return;
}

void draw_3polysouth(void)
{
x1=B12[q1][0];y1=B12[q1][1];z1=B12[q1][2];
x2=B12[q2][0];y2=B12[q2][1];z2=B12[q2][2];
x3=B11[0][0];y3=B11[0][1];z3=B11[0][2];
visibility_test(); if (sp>0) return;
sx1=B22[q2][0];sy1=B22[q2][1];
sx2=B22[q1][0];sy2=B22[q1][1];
sx3=B21[0][0];sy3=B21[0][1];
sx4=sx1;sy4=sy1;
x4=x1+0.5*(x2-x1);y4=y1+0.5*(y2-y1);z4=z1+0.5*(z2-z1);
x=x3+0.85*(x4-x3);y=y3+0.85*(y4-y3);z=z3+0.85*(z4-z3);
sx=d*x/z;sy=d*y/z;window();sx5=sx;sy5=sy;

draw_poly();
illumination();shade();dither();

return;
}

/*_________________________________________________________________

FUNCTION: identify center of polygon
*/
void polycenter(void)
{
x6=x2+0.5*(x1-x2);y6=y2+0.5*(y1-y2);z6=z2+0.5*(z1-z2);
x7=x3+0.5*(x4-x3);y7=y3+0.5*(y4-y3);z7=z3+0.5*(z4-z3);
x=x7+0.5*(x6-x7);y=y7+0.5*(y6-y7);z=z7+0.5*(z6-z7);
sx=d*x/z;sy=d*y/z;window();sx5=sx;sy5=sy;
return;
}

/*_________________________________________________________________

SUBROUTINE: calculate SIN,COS factors

enter with r1,r2,r3 viewing angles for yaw,roll,pitch
expressed in radians (0.0 thru 6.28319). returns sin,cos factors
*/

void rotation(void)
{
sr1=sin(r1);sr2=sin(r2);sr3=sin(r3);cr1=cos(r1);cr2=cos(r2);
cr3=cos(r3);
return;
}

/*______________________________________________________________

SUBROUTINE: standard 3D formulas

enter with x,y,z cartesian world coordinates.
returns sx,sy cartesian display coordinates.
returns x,y,z cartesian view coordinates.
*/

void calc_3d(void)
{
x=(-1)*x;xa=cr1*x-sr1*z;za=sr1*x+cr1*z;x=cr2*xa+sr2*y;
ya=cr2*y-sr2*xa;z=cr3*za-sr3*ya;y=sr3*za+cr3*ya;x=x+mx;y=y+my;
z=z+mz;sx=d*x/z;sy=d*y/z;
return;
}

/*_________________________________________________________________

FUNCTION: hidden surface visibility test
*/
void visibility_test(void)
{
sp1=x1*(y2*z3-y3*z2);sp1=(-1)*sp1;sp2=x2*(y3*z1-y1*z3);
sp3=x3*(y1*z2-y2*z1);sp=sp1-sp2-sp3;

return;
}

/*_____________________________________________________________

SUBROUTINE: draw 4-sided SOLID polygon in 3D space
*/

void draw_poly(void)
{
setlinestyle(USERBIT_LINE,0xffff,NORM_WIDTH);
setcolor(key_matte_clr);moveto(sx1,sy1);
lineto(sx2,sy2);lineto(sx3,sy3);lineto(sx4,sy4);lineto(sx1,sy1);
setfillstyle(SOLID_FILL,key_matte_clr);floodfill(sx5,sy5,key_matte_clr);
setcolor(edge_clr);moveto(sx1,sy1);
lineto(sx2,sy2);lineto(sx3,sy3);lineto(sx4,sy4);lineto(sx1,sy1);
setfillstyle(SOLID_FILL,solid_clr);floodfill(sx5,sy5,edge_clr);

return;
}

/*_____________________________________________________________

SUBROUTINE: calculate illumination level
*/

void illumination(void)
{
xu=x2-x1;yu=y2-y1;zu=z2-z1;
xv=x3-x1;yv=y3-y1;zv=z3-z1;
xn=(yu*zv)-(zu*yv);yn=(zu*xv)-(xu*zu);zn=(xu*yv)-(yu*xv);

yn=yn*(-1);zn=zn*(-1);
v1=(xn*xn)+(yn*yn)+(zn*zn);
v2=sqrt(v1); v3=1/v2;
xw=v3*xn;yw=v3*yn;zw=v3*zn;

v4=(xw*xs)+(yw*ys)+(zw*zs);

v4=v4*v6; v7=v4;; v5=v7+1;

return;
}

/*_____________________________________________________________

SUBROUTINE: illumination matrix
*/

void shade(void)
{
switch (v5)
{
case 1: setfillpattern(fill_6,NORM_HUE);CC6=0x1010;values();return;
case 2: setfillpattern(fill_6,NORM_HUE);CC6=0x1010;values();return;
case 3: setfillpattern(fill_6,NORM_HUE);CC6=0x1010;values();return;
case 4: setfillpattern(fill_12,NORM_HUE);CC6=0x2020;values();return;
case 5: setfillpattern(fill_25,NORM_HUE);CC6=0x2222;values();return;
case 6: setfillpattern(fill_37,NORM_HUE);CC6=0xaaaa;values();return;
case 7: setfillpattern(fill_50,NORM_HUE);CC6=0xaaaa;values();return;
case 8: setfillpattern(fill_62,NORM_HUE);CC6=0xaaaa;values();return;
case 9: setfillpattern(fill_75,NORM_HUE);CC6=0xbbbb;values();return;
case 10: setfillpattern(fill_87,NORM_HUE);CC6=0xdddd;values();return;
case 11: setfillpattern(fill_93,NORM_HUE);CC6=0xefef;values();return;
case 12: setfillpattern(fill_100,NORM_HUE);CC6=0xffff;values();return;
default: setfillpattern(fill_6,NORM_HUE);CC6=0x1010;values();
}

return;
}

/**** local subfunction ***/
void values(void)
{
floodfill(sx5,sy5,edge_clr);CC4=BASE_CLR;CC5=NORM_HUE;
return;
}

/*_____________________________________________________________

SUBROUTINE: apply dithering
*/

void dither(void)
{
setlinestyle(USERBIT_LINE,0xffff,NORM_WIDTH);setcolor(CC4);
moveto(sx1,sy1);lineto(sx2,sy2);lineto(sx3,sy3);
lineto(sx4,sy4);lineto(sx1,sy1);
setlinestyle(USERBIT_LINE,CC6,NORM_WIDTH);setcolor(CC5);
moveto(sx1,sy1);lineto(sx2,sy2);lineto(sx3,sy3);
lineto(sx4,sy4);lineto(sx1,sy1);

return;
}

/*_____________________________________________________________

SUBROUTINE: map coordinates to physical screen coordinates

enter with sx,sy cartesian coordinates.
returns sx,sy unclipped physical display coordinates.
*/

void window (void)
{
sx=sx+399;sy=sy+299;rx=screen_x/799;ry=screen_y/599;
sx=sx*rx;sy=sy*ry;
return;
}

/*_______________________________________________________________
SUBROUTINE: check the keyboard buffer */
void keyboard(void)
{
if (bioskey(1)==0) return; else quit_pgm();

}

/*____________________________________________________________________

SUBROUTINE: graceful exit from the program */

void quit_pgm(void)
{
cleardevice(); restorecrtmode();exit(0);
}

/*___________________________________________________________________
SUBROUTINE: vga/ega/cga/mcga compatibility module */

void graphics_setup(void)
{
int graphics_adapter,graphics_mode;
detectgraph(&graphics_adapter,&graphics_mode);
if (graphics_adapter==VGA) goto VGA_mode;
if (graphics_mode==EGAHI) goto EGA_ECD_mode;
if (graphics_mode==EGALO) goto EGA_SCD_mode;
if (graphics_adapter==CGA) goto abort_message;
if (graphics_adapter==MCGA) goto abort_message;
goto abort_message;

VGA_mode:
graphics_adapter=VGA;graphics_mode=VGAHI;
initgraph(&graphics_adapter,&graphics_mode,"");
x_res=640;y_res=480;mode_flag=1;
maxx=639;minx=0;maxy=479;miny=0;screen_x=639;screen_y=479;
setcolor(C7);
outtextxy(0,472,"640x480 16-color VGA mode");
outtextxy(168,0,"Using Turbo C to generate a solid 3D sphere");
moveto(472,472);outtext("Press any key to Quit...");
return;

EGA_ECD_mode:
graphics_adapter=EGA;graphics_mode=EGAHI;
initgraph(&graphics_adapter,&graphics_mode,"");
x_res=640;y_res=350;mode_flag=2;
maxx=639;minx=0;maxy=349;miny=0;screen_x=639;screen_y=349;
setcolor(C7);
outtextxy(0,342,"640x350 16-color EGA w/ECD mode");
outtextxy(168,0,"Using Turbo C to generate a solid 3D sphere");
moveto(472,342);outtext("Press any key to Quit...");
return;

EGA_SCD_mode:
graphics_adapter=EGA;graphics_mode=EGALO;
initgraph(&graphics_adapter,&graphics_mode,"");
x_res=640;y_res=200;mode_flag=3;
maxx=639;minx=0;maxy=199;miny=0;screen_x=639;screen_y=199;
setcolor(C7);
outtextxy(0,192,"640x200 16-color EGA w/SCD mode");
outtextxy(168,0,"Using Turbo C to generate a solid 3D sphere");
moveto(472,192);outtext("Press any key to Quit...");
return;

abort_message:
printf("\n\nUnable to proceed.\n");
printf("Requires VGA or EGA adapter\n");
printf(" with appropriate monitor.\n");
printf("Please refer to LEE ADAMS book HIGH-Perforamnce CAD Graphics in TURBO C.\n\n");
exit(0);
}
/*__________________________________________________________
SUBROUTINE: coords()

accepts sx,sy device independent display coordinates
and returns sx,sy device-dependent screen coordinates
scaled to fit your display.
*/

void coords(void)
{
sx=sx*(x_res/640);sy=sy*(y_res/480);
return;
}

/*__________________________________________________________
SUBROUTINE: copyright notice */

int copyright[][3]={0x7c00,0x0000,0x0000,0x8231,
0x819c,0x645e,0xba4a,0x4252,0x96d0,0xa231,0x8252,0x955e,0xba4a,
0x43d2,0xf442,0x8231,0x825c,0x945e,0x7c00,0x0000,0x0000};

void notice(int x, int y)
{
int a,b,c; int t1=0;
for (t1=0;t1<=6;t1++){a=copyright[t1][0];b=copyright[t1][1];
c=copyright[t1][2];
setlinestyle(USERBIT_LINE,a,NORM_WIDTH);
moveto(x,y);lineto(x+15,y);
setlinestyle(USERBIT_LINE,b,NORM_WIDTH);
moveto(x+16,y);lineto(x+31,y);
setlinestyle(USERBIT_LINE,c,NORM_WIDTH);
moveto(x+32,y);lineto(x+47,y);y=y+1;
}
setlinestyle(USERBIT_LINE,0xFFFF,NORM_WIDTH);
return;
}
/* END */


  3 Responses to “Category : C Source Code
Archive   : CADSRC.ZIP
Filename : T-11.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/