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