/* make an dodecahedron
 *
 * 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.
 */

#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 FACES 12

#undef LABEL

typedef double point[3];

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 */
};

/* 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}
};

/* output vertex v[n], converted to 2d */
void wrvx(int n) {
  printf("%.4lg %.4lg",400*v[n][0]/(v[n][2]+5)+200,400*v[n][1]/(v[n][2]+5)+200);
}

/* output points for face faces[n] */
void facepath(int n) {
  int i;
  printf("  Move "); wrvx(faces[n][0]);
  for (i=1;i<5;++i) {
    printf("\n  Line "); wrvx(faces[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<5;++i) {
    x+=v[faces[n][i]][0];
    y+=v[faces[n][i]][1];
    z+=v[faces[n][i]][2];
  }
  x/=5; y/=5; z/=5;
  return (x*x+y*y+(z+5)*z<0);
}

int main(int ac, char *av[]) {
  int i;
  double ax,ay,az;
  if (ac!=4) {
    fprintf(stderr,"Usage: dodec 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;
  { 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<20;++i) {
      x=v[i][0]; y=v[i][1]; z=v[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;
      v[i][0]=x; v[i][1]=y; v[i][2]=z;
    }
  }
#ifdef LABEL
  printf("FontTable {\n  1 Trinity.Medium\n}\n");
  for (i=0;i<20;++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<FACES;++i) {
    if (visible(i)) facepath(i);
  }
  printf("}\n\nPath {\n  Style { Dash { 1 4 } }\n");
  for (i=0;i<FACES;++i){
    if (!visible(i)) facepath(i);
  }
  printf("}\n");
  return 0;
}
