home *** CD-ROM | disk | FTP | other *** search
- /* make an icosahedron
- *
- * The Clever Fact is: you can make a dodecahedron by starting with a cube
- * and putting a "tent" on top of each face. The tent needs to have "height"
- * (root5-1)/2, and "offset" the square of that.
- *
- * And the icosahedron is the dual of the dodecahedron.
- * This program is very similar to dodec.c .
- */
-
- #include <math.h>
- #include <stdio.h>
-
- #define HEIGHT 0.61803398875
- #define OFFSET 0.38196601125 /* HEIGHT^2 */
- #define BIG (1+HEIGHT)
- #define SMALL (1-OFFSET)
-
- #define DISTANCE 10
-
- #define FACES 12
-
- #undef LABEL
-
- typedef double point[3];
-
- /* vertices of dodecahedron */
- point v[20] = {
- /* vertices of cube */
- { -1,-1,-1 }, /* 0 */
- { -1,-1, 1 }, /* 1 */
- { -1, 1,-1 }, /* 2 */
- { -1, 1, 1 }, /* 3 */
- { 1,-1,-1 }, /* 4 */
- { 1,-1, 1 }, /* 5 */
- { 1, 1,-1 }, /* 6 */
- { 1, 1, 1 }, /* 7 */
- { -SMALL, 0, -BIG }, /* 8 */
- { SMALL, 0, -BIG }, /* 9 */
- { -SMALL, 0, BIG }, /* 10 */
- { SMALL, 0, BIG }, /* 11 */
- { 0, -BIG, -SMALL }, /* 12 */
- { 0, -BIG, SMALL }, /* 13 */
- { 0, BIG, -SMALL }, /* 14 */
- { 0, BIG, SMALL }, /* 15 */
- { -BIG, -SMALL, 0 }, /* 16 */
- { -BIG, SMALL, 0 }, /* 17 */
- { BIG, -SMALL, 0 }, /* 18 */
- { BIG, SMALL, 0 }, /* 19 */
- };
-
- /* faces of dodecahedron */
- /* this is an arbitrary order */
- int faces[FACES][5] = {
- {0,12,13,1,16},
- {4,12,13,5,18},
- {0,16,17,2,8},
- {6,9,4,18,19},
- {0,8,9,4,12},
- {2,14,6,9,8},
- {1,13,5,11,10},
- {3,10,11,7,15},
- {1,10,3,17,16},
- {5,18,19,7,11},
- {2,17,3,15,14},
- {6,14,15,7,19}
- };
-
- /* will contain vertices of icosahedron */
- point w[12];
-
- /* will contain faces of icosahedron */
- int f[20][3];
- int nv[20]; /* how many vertices of this face so far? */
-
- /* output vertex w[n], converted to 2d */
- void wrvx(int n) {
- printf("%.4lg %.4lg",(DISTANCE-1)*100*w[n][0]/(w[n][2]+DISTANCE)+200,
- (DISTANCE-1)*100*w[n][1]/(w[n][2]+DISTANCE)+200);
- }
-
- /* output points for face f[n] */
- void facepath(int n) {
- int i;
- printf(" Move "); wrvx(f[n][0]);
- for (i=1;i<3;++i) {
- printf("\n Line "); wrvx(f[n][i]); }
- printf("\n Close\n");
- }
-
- /* is face n visible from 0,0,-5 ? */
- int visible(int n) {
- double x=0,y=0,z=0;
- int i;
- for (i=0;i<3;++i) {
- x+=w[f[n][i]][0];
- y+=w[f[n][i]][1];
- z+=w[f[n][i]][2];
- }
- x/=3; y/=3; z/=3;
- return (x*x+y*y+(z+DISTANCE)*z<0);
- }
-
- int main(int ac, char *av[]) {
- int i;
- double ax,ay,az;
- if (ac!=4) {
- fprintf(stderr,"Usage: icos angleX angleY angleZ\n");
- return 0;
- }
- sscanf(av[1],"%lf",&ax); ax*=3.141592653589793/180;
- sscanf(av[2],"%lf",&ay); ay*=3.141592653589793/180;
- sscanf(av[3],"%lf",&az); az*=3.141592653589793/180;
- /* set up vertex and face arrays for icos from those for dodec */
- { double x,y,z; int j; int n;
- for (i=0;i<12;++i) {
- x=0; y=0; z=0;
- for (j=0;j<5;++j) {
- n=faces[i][j];
- x+=v[n][0];
- y+=v[n][1];
- z+=v[n][2];
- f[n][nv[n]++]=i;
- }
- w[i][0]=x/5; w[i][1]=y/5; w[i][2]=z/5;
- }
- }
- { double cx=cos(ax),sx=sin(ax),cy=cos(ay),sy=sin(ay),cz=cos(az),sz=sin(az);
- double t,x,y,z;
- for (i=0;i<12;++i) {
- x=w[i][0]; y=w[i][1]; z=w[i][2];
- t=x; x=x*cz-y*sz; y=t*sz+y*cz;
- t=x; x=x*cy-z*sy; z=t*sy+z*cy;
- t=y; y=y*cx-z*sx; z=t*sx+z*cx;
- w[i][0]=x; w[i][1]=y; w[i][2]=z;
- }
- }
- #ifdef LABEL
- printf("FontTable {\n 1 Trinity.Medium\n}\n");
- for (i=0;i<12;++i) {
- printf("\nText {\n Style 1\n Size 12 12\n StartAt "); wrvx(i);
- printf("\n Text %d\n}\n",i);
- }
- #endif
- printf("\nPath {\n");
- for (i=0;i<20;++i) {
- if (visible(i)) facepath(i);
- }
- printf("}\n\nPath {\n Style { Dash { 1 4 } }\n");
- for (i=0;i<20;++i){
- if (!visible(i)) facepath(i);
- }
- printf("}\n");
- return 0;
- }
-