home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / tc_3d / tc-04hol.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-13  |  10.6 KB  |  351 lines

  1. /* tc-04 - remake */
  2.  
  3. /* This program draws a solid 3d sphere using the plain equation
  4.     method of hidden surface removal.*/
  5.  
  6. /* ----------------------------------------------------------------------- */
  7. /* INCLUDE FILES */
  8. #include <process.h>
  9. #include <bios.h>
  10. #include <stdio.h>
  11. #include <graphics.h>
  12. #include <math.h>
  13.  
  14. /* ----------------------------------------------------------------------- */
  15. /* DECLARATIONS */
  16. /* global variables */
  17.  
  18. float        x=0.0,y=0.0,z=0.0;
  19. float        x1=0.0,x2=0.0,x3=0.0,x4=0.0;
  20. float        y01=0.0,y2=0.0,y3=0.0,y4=0.0;
  21. float        z1=0.0,z2=0.0,z3=0.0,z4=0.0;
  22. float        sx1=0.0,sx2=0.0,sx3=0.0,sx4=0.0,sx5=0.0;
  23. float        sy1=0.0,sy2=0.0,sy3=0.0,sy4=0.0,sy5=0.0;
  24. float        sx=0.0,sy=0.0;
  25. float        xa=0.0,ya=0.0,za=0.0;
  26. float        d=1200.0;
  27. double    r1=6.19592;
  28. double    r2=.523590;
  29. double    r3=5.39778;
  30. double    sr1=0.0,sr2=0.0,sr3=0.0;
  31. double    cr1=0.0,cr2=0.0,cr3=0.0;
  32. float        mx=0.0,my=0.0,mz=-160;
  33. int        maxx=839,minx=0,maxy=199,miny=0;
  34. float        screen_x=639,screen_y=199;
  35. float        rx=0.0,ry=0.0;
  36. int        t=0,t1=0,t2=0;
  37. int        p1=0;
  38. int        C0=0,C1=1,C2=2,C3=3,C4=4,C5=5,C6=6,C7=7,C8=8,C9=9,
  39.             C10=10,C11=11,C12=12,C13=13,C14=14,C15=15,
  40.             mode_flag=0;
  41. int        key_matte_clr=6;
  42. int        edge_clr=7;
  43. int        solid_clr=0;
  44. float        x_res,y_res;
  45. float        sp=0.0;
  46. float        sp1=0.0,sp2=0.0,sp3=0.0;
  47. float        xlarge=0.0,xsmall=0.0;
  48. float    ylarge=0.0,ysmall=0.0;
  49. float        zlarge=0.0,zsmall=0.0;
  50. float        x6=0.0,x7=0.0,y6=0.0,y7=0.0,z6=0.0,z7=0.0;
  51.  
  52. int        q=0,q1=0,q2=0;
  53. double    r4=6.28319,r5=6.28319;
  54. float        B11[36][3];
  55. float        B12[36][3];
  56. float        B21[36][2];
  57. float        B22[36][2];
  58. int        polary[4][2];  /* used in my 3d solid polygon draw routine */
  59. double    sr4=0.0,cr4=0.0,sr5=0.0,cr5=0.0;
  60.  
  61. /* declare global subroutines */
  62. void keyboard(void);void quit_pgm(void);void calc_3d(void);
  63. void rotation(void);void window(void);void graphics_setup(void);
  64. void coords(void);void draw_poly(void);void notice(int x,int y);
  65. void visibility_test(void);void polycenter(void);
  66.  
  67. void sphere_coords(void);void draw_4poly(void);
  68. void draw_3polynorth(void);void draw_3polysouth(void);
  69. void upper_coords(void);void lower_coords(void);
  70.  
  71. /* ----------------------------------------------------------------------- */
  72. /* MAIN ROUTINE */
  73. main(){
  74. graphics_setup();
  75. setviewport(0,0,maxx,maxy,1);
  76. key_matte_clr=C6;
  77. edge_clr=C7;solid_clr=C0;
  78. rotation();
  79.  
  80. /* DRAW NORTH POLAR REGION */
  81. r5=0.0;r4=0.0;x=30;sphere_coords();calc_3d();window();
  82. B11[0][0]=x;B11[0][1]=y;B11[0][2]=z;
  83. B21[0][0]=sx;B21[0][1]=sy;
  84. x=30;r5=.17453;r4=0.0;lower_coords();
  85. for (q1=0;q1<=35;q1++){
  86.     q2=q1+1;if (q2>35) q2=0;
  87.     draw_3polynorth();
  88.     keyboard();
  89. }
  90.  
  91. /* DRAW POLYGONS ALONG BELTS OF SPHERES */
  92. r5=.17453;
  93. for (t2=1;t2<=16;t2++){
  94.     x=30;r4=0.0;upper_coords();
  95.     x=30;r5=r5+.17453;r4=0.0;lower_coords();
  96.     for (q1=0;q1<=35;q1++){
  97.         q2=q1+1;if (q2>35) q2=0;
  98.         draw_4poly();
  99.         keyboard();
  100.         }
  101.     }
  102.  
  103. /* DRAW SOUTH POLAR REGIONS */
  104. r5=3.14159;r4=0.0;x=30;sphere_coords();calc_3d();window();
  105. B21[0][0]=x;B21[0][1]=y;B21[0][2]=z;
  106. B22[0][0]=sx;B22[0][1]=sy;
  107. x=30;r5=2.96706;r4=0.0;upper_coords();
  108. for (q1=0;q1<=35;q1++){
  109.     q2=q1+1;if (q2>35) q2=0;
  110.     draw_3polysouth();
  111.     keyboard();
  112. }
  113.  
  114. setcolor(C7);notice(0,0);
  115. for (t1=1;t1!=2;) keyboard();
  116. quit_pgm();
  117. }
  118.  
  119. /* ----------------------------------------------------------------------- */
  120. /* SUBROUTINE: CALCULATE AND STORE COORDS FOR BELT */
  121.  
  122. void upper_coords(void){
  123. for (t=0;t<=35;t++){
  124.     x=30;sphere_coords();calc_3d();window();
  125.     B11[t][0]=x;B11[t][1]=y;B11[t][2]=z;
  126.     B21[t][0]=sx;B21[t][1]=sy;
  127.     r4=r4+.17453;
  128.     keyboard();}
  129.     return;}
  130.  
  131. void lower_coords(void){
  132.     for (t=0;t<=35;t++){
  133.     x=30;sphere_coords();calc_3d();window();
  134.     B12[t][0]=x;B12[t][1]=y;B12[t][2]=z;
  135.     B22[t][0]=sx;B22[t][1]=sy;
  136.     r4=r4+.17453;
  137.     keyboard();}
  138. return;}
  139.  
  140. /* ----------------------------------------------------------------------- */
  141. /* SUBROUTINE: CALCULATE WORLD COORDINATES FOR SPHERE */
  142.  
  143. void sphere_coords(void){
  144. sr4=sin(r4);cr4=cos(r4);sr5=sin(r5);
  145. cr5=cos(r5);x1=sr5*x;y=cr5*x;x=cr4*x1;z=sr4*x1;return;}
  146.  
  147. /* ----------------------------------------------------------------------- */
  148. /* SUBROUTINE: DRAW 4 SIDED POLYGON SURFACE ON SPHERE */
  149.  
  150. void draw_4poly(void){
  151. x1=B11[q1][0];y01=B11[q1][1];z1=B11[q1][2];
  152. x2=B11[q2][0];y2=B11[q2][1];z2=B11[q2][2];
  153. x3=B12[q2][0];y3=B12[q2][1];z3=B12[q2][2];
  154. x4=B12[q1][0];y4=B12[q1][1];z4=B12[q1][2];
  155. sx1=B21[q1][0];sy1=B21[q1][1];
  156. sx2=B21[q2][0];sy2=B21[q2][1];
  157. sx3=B22[q2][0];sy3=B22[q2][1];
  158. sx4=B22[q1][0];sy4=B22[q1][1];
  159. polycenter();
  160. draw_poly();
  161. return;}
  162.  
  163. /* ----------------------------------------------------------------------- */
  164. /* SUBROUTINE: DRAW 3 SIDED POLYGONAL SURFACE ON SPHERE */
  165.  
  166. void draw_3polynorth(void){
  167. x1=B12[q2][0];y01=B12[q2][1];z1=B12[q2][2];
  168. x2=B12[q1][0];y2=B12[q1][1];z2=B12[q1][2];
  169. x3=B11[0][0];y3=B11[0][1];z3=B11[0][2];
  170. sx1=B22[q2][0];sy1=B22[q2][1];
  171. sx2=B22[q1][0];sy2=B22[q1][1];
  172. sx3=B21[0][0];sy3=B21[0][1];
  173. sx4=sx1;sy4=sy1;
  174. x4=x1+.5*(x2-x1);y4=y01+.5*(y2-y01);z4=z1+.5*(z2-z1);
  175. x=x3+.85*(x4-x3);y=y3+.85*(y4-y3);z=z3+.85*(z4-z3);
  176. sx=d*x/z;sy=d*y/z;window();sx5=sx;sy5=sy;
  177. draw_poly();
  178. return;}
  179.  
  180. void draw_3polysouth(void){
  181. x1=B12[q1][0];y01=B12[q1][1];z1=B12[q1][2];
  182. x2=B12[q2][0];y2=B12[q2][1];z2=B12[q2][2];
  183. x3=B11[0][0];y3=B11[0][1];z3=B11[0][2];
  184. sx1=B21[q2][0];sy1=B21[q2][1];
  185. sx2=B22[q1][0];sy2=B22[q1][1];
  186. sx3=B22[0][0];sy3=B22[0][1];
  187. sx4=sx1;sy4=sy1;
  188. x4=x1+.5*(x2-x1);y4=y01+.5*(y2-y01);z4=z1+.5*(z2-z1);
  189. x=x3+.85*(x4-x3);y=y3+.85*(y4-y3);z=z3+.85*(z4-z3);
  190. sx=d*x/z;sy=d*y/z;window();sx5=sx;sy5=sy;
  191. draw_poly();
  192. return;}
  193.  
  194. /* ----------------------------------------------------------------------- */
  195. /* SUBROUTINE: IDENTIFY CENTER OF POLYGON */
  196.  
  197. void polycenter(void){x6=x2+.5*(x1-x2);y6=y2+.5*(y01-y2);
  198. z6=z2+.5*(z1-z2);x7=x3+.5*(x4-x3);y7=y3+.5*(y4-y3);z7=z3+.5*(z4-z3);
  199. x=x7+.5*(x6-x7);y=y7+.5*(y6-y7);z=z7+.5*(z6-z7);sx=d*x/z;sy=d*y/z;
  200. window();sx5=sx;sy5=sy;return;}
  201.  
  202. /* ----------------------------------------------------------------------- */
  203. /* SUBROUTINE: CALCULATE SIN,COS FACTORS */
  204.  
  205. void rotation(void){
  206. sr1=sin(r1);sr2=sin(r2);sr3=sin(r3);cr1=cos(r1);cr2=cos(r2);
  207. cr3=cos(r3);return;}
  208.  
  209. /* ----------------------------------------------------------------------- */
  210. /* SUBROUTINE: STANDARD 3D FORMULAS */
  211. /* Pass: x,y,z cartesian world coordinates.
  212.    Returns: sx,sy cartesian display coordinates.
  213.           x,y,z catesian view coordinates */
  214.  
  215. void calc_3d(void){
  216. x=(-1)*x;xa=cr1*x-sr1*z;za=sr1*x+cr1*z;x=cr2*xa+sr2*y;
  217. ya=cr2*y-sr2*xa;z=cr3*za-sr3*ya;y=sr3*za+cr3*ya;x=x+mx;y=y+my;
  218. z=z+mz;sx=d*x/z;sy=d*y/z;return;}
  219.  
  220. /* ----------------------------------------------------------------------- */
  221. /* HIDDEN SURFACE VISIBILTY TEST */
  222. void visibility_test(void){
  223. sp1=x1*(y2*z3-y3*z2);sp1=(-1)*sp1;sp2=x2*(y3*z1-y01*z3);
  224. sp3=x3*(y01*z2-y2*z1);sp=sp1-sp2-sp3;return;}
  225.  
  226. /* ----------------------------------------------------------------------- */
  227. /* SUBROUTINE: DRAW 4-SIDED SOLID POLYGON IN 3D SPACE */
  228.  
  229. void draw_poly(void){
  230. setlinestyle(USERBIT_LINE,0xffff,NORM_WIDTH);
  231. setfillstyle(SOLID_FILL,solid_clr);
  232. setcolor(edge_clr);
  233.  
  234. polary[0][0]=sx1;polary[0][1]=sy1;polary[1][0]=sx2;polary[1][1]=sy2;
  235. polary[2][0]=sx3;polary[2][1]=sy3;polary[3][0]=sx4;polary[3][1]=sy4;
  236.  
  237. drawpoly (4,(int far*) polary);
  238. return;
  239. }
  240.  
  241. /* ----------------------------------------------------------------------- */
  242. /* SUBROUTINE: MAP CARTESIAN COORDS TO PHYSICAL SCREEN COORDS */
  243.  
  244. void window(void){
  245. sx=sx+399;sy=sy+299;rx=screen_x/799;ry=screen_y/599;sx=sx*rx;
  246. sy=sy*ry;return;}
  247.  
  248. /* ----------------------------------------------------------------------- */
  249. /* SUBROUTINE: CHACK THE KEYBOARD BUFFER */
  250. void keyboard(void){
  251. if (bioskey(1)==0) return; else quit_pgm();}
  252.  
  253. /* ----------------------------------------------------------------------- */
  254. /* SUBROUTINE: GRACEFUL EXIT FROM PROGRAM */
  255.  
  256. void quit_pgm(void){
  257. cleardevice();restorecrtmode();exit(0);}
  258.  
  259. /* ----------------------------------------------------------------------- */
  260. /* SUBROUTINE: VGA/EGA/MCGA/CGA COMPATIBILITY MODULE */
  261.  
  262. void graphics_setup(void){
  263. int graphics_adapter,graphics_mode;
  264. detectgraph(&graphics_adapter,&graphics_mode);
  265. if (graphics_adapter==VGA) goto VGA_mode;
  266. if (graphics_mode==EGAHI) goto EGA_ECD_mode;
  267. if (graphics_mode==EGALO) goto EGA_SCD_mode;
  268. if (graphics_adapter==CGA) goto abort_message;
  269. if (graphics_adapter==MCGA) goto abort_message;
  270. goto abort_message;
  271.  
  272. VGA_mode:
  273. graphics_adapter=VGA;graphics_mode=VGAHI;
  274. initgraph(&graphics_adapter,&graphics_mode,"");
  275. x_res=640;y_res=480;mode_flag=1;
  276.     maxx=639;minx=0;maxy=479;miny=0;screen_x=639;screen_y=479;
  277.     setcolor(7);moveto(0,472);
  278.     outtext("Revisions by A. Helder");
  279.     moveto(472,472);
  280.     outtext("Press any key to quit");
  281.     moveto(160,0);
  282.     outtext("USING C TO GENERATE A HOLLOW 3D SPHERE");
  283.     return;
  284.  
  285. EGA_ECD_mode:
  286. graphics_adapter=EGA;graphics_mode=EGAHI;
  287. initgraph(&graphics_adapter,&graphics_mode,"");
  288. x_res=640;y_res=350;mode_flag=2;
  289.     maxx=639;minx=0;maxy=349;miny=0;screen_x=639;screen_y=349;
  290.     setcolor(7);moveto(0,342);
  291.     outtext("Revisions by A. Helder");
  292.     moveto(472,342);
  293.     outtext ("Press any key to quit");
  294.     moveto(160,0);
  295.     outtext("USING C TO GENERATE A HOLLOW 3D SPHERE");
  296.     return;
  297.  
  298. EGA_SCD_mode:
  299. graphics_adapter=EGA;graphics_mode=EGALO;
  300. initgraph(&graphics_adapter,&graphics_mode,"");
  301. x_res=640;y_res=200;mode_flag=3;
  302.     maxx=639;minx=0;maxy=199;miny=0;screen_x=639;screen_y=199;
  303.     setcolor(7);moveto(0,192);
  304.     outtext("Revisions by A. Helder");
  305.     moveto(472,192);
  306.     outtext("PRESS ANY KEY TO QUIT");
  307.     moveto(160,0);
  308.     outtext("USING C TO GENERATE A HOLLOW 3D SPHERE");
  309.     return;
  310.  
  311.  
  312. abort_message:
  313. printf("\n\nUnable to proceed - Requires VGA or EGA adapter");
  314. printf("\nWith appropriate monitor");
  315. exit(0);
  316. }
  317.  
  318. /* ----------------------------------------------------------------------- */
  319. /* SUBROUTINE: MAP 640*480 TEMPLATE TO 2D SCREEN */
  320. void coords(void)
  321. {
  322. sx=sx*(x_res/640);sy=sy*(y_res/480);return;
  323. }
  324.  
  325. /* ----------------------------------------------------------------------- */
  326. /* SUBROUTINE: COPYRIGHT NOTICE */
  327.  
  328. int copyright[][3]={0x7c00,0x0000,0x0000,0x8231,
  329. 0x819c,0x645e,0xba4a,0x4252,0x96d0,0xa231,0x8252,0x955e,0xba4a,
  330. 0x43d2,0xf442,0x8231,0x825c,0x945e,0x7c00,0x0000,0x0000};
  331.  
  332. void notice(int x, int y){
  333. int a,b,c; int t1=0;
  334.  
  335. for (t1=0;t1<=6;t1++)
  336.     {
  337.     a=copyright[t1][0];b=copyright[t1][1];
  338.     c=copyright[t1][2];
  339.     setlinestyle(USERBIT_LINE,a,NORM_WIDTH);
  340.     moveto(x,y);lineto(x+15,y);
  341.     setlinestyle(USERBIT_LINE,b,NORM_WIDTH);
  342.     moveto(x+16,y);lineto(x+31,y);
  343.     setlinestyle(USERBIT_LINE,c,NORM_WIDTH);
  344.     moveto(x+32,y);lineto(x+47,y);y++;
  345.     };
  346. setlinestyle(USERBIT_LINE,0xFFFF,NORM_WIDTH);
  347. return;}
  348.  
  349.  
  350. /* ----------------------------------------------------------------------- */
  351.