home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / utilities / utilsm / mkdrawf / Goodies / c / icos < prev    next >
Text File  |  1995-04-11  |  4KB  |  156 lines

  1. /* make an icosahedron
  2.  *
  3.  * The Clever Fact is: you can make a dodecahedron by starting with a cube
  4.  * and putting a "tent" on top of each face. The tent needs to have "height"
  5.  * (root5-1)/2, and "offset" the square of that.
  6.  *
  7.  * And the icosahedron is the dual of the dodecahedron.
  8.  * This program is very similar to dodec.c .
  9.  */
  10.  
  11. #include <math.h>
  12. #include <stdio.h>
  13.  
  14. #define HEIGHT    0.61803398875
  15. #define OFFSET    0.38196601125    /* HEIGHT^2 */
  16. #define BIG    (1+HEIGHT)
  17. #define SMALL    (1-OFFSET)
  18.  
  19. #define DISTANCE 10
  20.  
  21. #define FACES 12
  22.  
  23. #undef LABEL
  24.  
  25. typedef double point[3];
  26.  
  27. /* vertices of dodecahedron */
  28. point v[20] = {
  29.     /* vertices of cube */
  30.   { -1,-1,-1 },    /* 0 */
  31.   { -1,-1, 1 },    /* 1 */
  32.   { -1, 1,-1 },    /* 2 */
  33.   { -1, 1, 1 },    /* 3 */
  34.   {  1,-1,-1 },    /* 4 */
  35.   {  1,-1, 1 },    /* 5 */
  36.   {  1, 1,-1 },    /* 6 */
  37.   {  1, 1, 1 },    /* 7 */
  38.   { -SMALL, 0, -BIG },    /* 8 */
  39.   {  SMALL, 0, -BIG },    /* 9 */
  40.   { -SMALL, 0,  BIG },    /* 10 */
  41.   {  SMALL, 0,  BIG },    /* 11 */
  42.   { 0, -BIG, -SMALL },    /* 12 */
  43.   { 0, -BIG,  SMALL },    /* 13 */
  44.   { 0,  BIG, -SMALL },    /* 14 */
  45.   { 0,  BIG,  SMALL },    /* 15 */
  46.   { -BIG, -SMALL, 0 },    /* 16 */
  47.   { -BIG,  SMALL, 0 },    /* 17 */
  48.   {  BIG, -SMALL, 0 },    /* 18 */
  49.   {  BIG,  SMALL, 0 },    /* 19 */
  50. };
  51.  
  52. /* faces of dodecahedron */
  53. /* this is an arbitrary order */
  54. int faces[FACES][5] = {
  55.   {0,12,13,1,16},
  56.   {4,12,13,5,18},
  57.   {0,16,17,2,8},
  58.   {6,9,4,18,19},
  59.   {0,8,9,4,12},
  60.   {2,14,6,9,8},
  61.   {1,13,5,11,10},
  62.   {3,10,11,7,15},
  63.   {1,10,3,17,16},
  64.   {5,18,19,7,11},
  65.   {2,17,3,15,14},
  66.   {6,14,15,7,19}
  67. };
  68.  
  69. /* will contain vertices of icosahedron */
  70. point w[12];
  71.  
  72. /* will contain faces of icosahedron */
  73. int f[20][3];
  74. int nv[20];    /* how many vertices of this face so far? */
  75.  
  76. /* output vertex w[n], converted to 2d */
  77. void wrvx(int n) {
  78.   printf("%.4lg %.4lg",(DISTANCE-1)*100*w[n][0]/(w[n][2]+DISTANCE)+200,
  79.                        (DISTANCE-1)*100*w[n][1]/(w[n][2]+DISTANCE)+200);
  80. }
  81.  
  82. /* output points for face f[n] */
  83. void facepath(int n) {
  84.   int i;
  85.   printf("  Move "); wrvx(f[n][0]);
  86.   for (i=1;i<3;++i) {
  87.     printf("\n  Line "); wrvx(f[n][i]); }
  88.   printf("\n  Close\n");
  89. }
  90.  
  91. /* is face n visible from 0,0,-5 ? */
  92. int visible(int n) {
  93.   double x=0,y=0,z=0;
  94.   int i;
  95.   for (i=0;i<3;++i) {
  96.     x+=w[f[n][i]][0];
  97.     y+=w[f[n][i]][1];
  98.     z+=w[f[n][i]][2];
  99.   }
  100.   x/=3; y/=3; z/=3;
  101.   return (x*x+y*y+(z+DISTANCE)*z<0);
  102. }
  103.  
  104. int main(int ac, char *av[]) {
  105.   int i;
  106.   double ax,ay,az;
  107.   if (ac!=4) {
  108.     fprintf(stderr,"Usage: icos angleX angleY angleZ\n");
  109.     return 0;
  110.   }
  111.   sscanf(av[1],"%lf",&ax); ax*=3.141592653589793/180;
  112.   sscanf(av[2],"%lf",&ay); ay*=3.141592653589793/180;
  113.   sscanf(av[3],"%lf",&az); az*=3.141592653589793/180;
  114.     /* set up vertex and face arrays for icos from those for dodec */
  115.   { double x,y,z; int j; int n;
  116.     for (i=0;i<12;++i) {
  117.       x=0; y=0; z=0;
  118.       for (j=0;j<5;++j) {
  119.         n=faces[i][j];
  120.         x+=v[n][0];
  121.         y+=v[n][1];
  122.         z+=v[n][2];
  123.         f[n][nv[n]++]=i;
  124.       }
  125.       w[i][0]=x/5; w[i][1]=y/5; w[i][2]=z/5;
  126.     }
  127.   }
  128.   { double cx=cos(ax),sx=sin(ax),cy=cos(ay),sy=sin(ay),cz=cos(az),sz=sin(az);
  129.     double t,x,y,z;
  130.     for (i=0;i<12;++i) {
  131.       x=w[i][0]; y=w[i][1]; z=w[i][2];
  132.       t=x; x=x*cz-y*sz; y=t*sz+y*cz;
  133.       t=x; x=x*cy-z*sy; z=t*sy+z*cy;
  134.       t=y; y=y*cx-z*sx; z=t*sx+z*cx;
  135.       w[i][0]=x; w[i][1]=y; w[i][2]=z;
  136.     }
  137.   }
  138. #ifdef LABEL
  139.   printf("FontTable {\n  1 Trinity.Medium\n}\n");
  140.   for (i=0;i<12;++i) {
  141.     printf("\nText {\n  Style 1\n  Size 12 12\n  StartAt "); wrvx(i);
  142.     printf("\n  Text %d\n}\n",i);
  143.   }
  144. #endif
  145.   printf("\nPath {\n");
  146.   for (i=0;i<20;++i) {
  147.     if (visible(i)) facepath(i);
  148.   }
  149.   printf("}\n\nPath {\n  Style { Dash { 1 4 } }\n");
  150.   for (i=0;i<20;++i){
  151.     if (!visible(i)) facepath(i);
  152.   }
  153.   printf("}\n");
  154.   return 0;
  155. }
  156.