/* dual.c - sdt - 20-OCT-1985 - create a transformation between the * purple octohedron and the blue cube, * to illustrate that they are dual * Platonic solids. * * usage: dual [filename] * if no file is given, the formatted data will go to stdout. * if the named file exists, program will abort. * example: dual x.x * crystal -r x.x * * mods 03-NOV-1985 to take advantage of the auto reverse mode (-r) * added to crystal (the program that displays 3d movies). */ #include "stdio.h" static int nlines = 9 ; /* primitives based on octohedron; (a,b,c) -> (x,y,z) later. */ static float a[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 0.5, 0.0 } ; static float b[] = { 0.0, 0.0, 0.5, 1.0, 1.0, 0.5, 0.0, 0.0, 0.0, 0.0 } ; static float c[] = { 1.0, 1.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 1.0 } ; static int upo[] = { 2, 1, 1, 2, 1, 1, 2, 1, 1, 0 } ; /* primitives based on cube; (d,e,f) -> (x,y,z) later. */ static float d[] = { 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 } ; static float e[] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0 } ; static float f[] = { 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0 } ; static int upc[] = { 2, 1, 1, 2, 1, 1, 2, 1, 1, 0 } ; /* the format string to use when writing x,y,z,up. */ static char *fmt = { "%.3f %.3f %.3f %1d\n" } ; /* scaled to inscribe the unit sphere */ float x[10], y[10], z[10] ; double pi ; main( argc, argv ) int argc; char *argv[] ; { FILE *fp ; extern FILE *fopen() ; extern int fclose() ; extern double atan() ; pi = atan( 1.0 ) * 4.0 ; if( argc == 1 ) { /* no args */ dual( stdout ) ; } else { if( (fp = fopen( *++argv, "r" )) != NULL ) abort( "dual: file %s exists - will not overwrite!", *argv ) ; if( (fp = fopen( *argv, "w" )) == NULL ) abort( "dual: can't open %s for output", *argv ) ; dual( fp ) ; fclose( fp ) ; } } dual( fp ) FILE *fp ; { int i, j ; /* loop index */ int jmax = 40 ; extern int scale() ; extern double cos() ; float sigma ; for( j = 0 ; j < jmax ; j++ ) { fprintf( stderr, "j=%d\n", j ) ; sigma = (float)j / (float)jmax ; sigma = (1.0 - cos( sigma * pi )) * 0.5 ; octo( sigma ); scale() ; spit( fp, upo ) ; } for( j = 0 ; j < jmax ; j++ ) { fprintf( stderr, "j=%d\n", j ) ; sigma = 1.0 - (float)j / (float)jmax ; sigma = (1.0 - cos( sigma * pi )) * 0.5 ; cube( sigma ) ; scale() ; spit( fp, upc ) ; } } int scale() /* return 0 if it worked, else 1 */ { int i ; extern double sqrt() ; double sqrad ; /* square of radius */ double maxsq ; /* max of the squares */ double maxradi ; /* one over maximum squared radius */ for( maxsq = 0.0, i = 0 ; i <= nlines ; i++ ) if( maxsq < (sqrad = x[i] * x[i] + y[i] * y[i] + z[i] * z[i]) ) maxsq = sqrad ; if( maxsq > 0.0 ) { maxradi = 1.0 / sqrt( maxsq ) ; for( i = 0 ; i <= nlines ; i++ ) { x[i] *= maxradi ; y[i] *= maxradi ; z[i] *= maxradi ; } return( 0 ) ; } else return( 1 ) ; } spit( fp, up ) FILE *fp ; int *up ; { int i ; fprintf( fp, "%d\n", (nlines + 1) * 8 - 1) ; for( i = 0 ; i <= nlines ; i++ ) fprintf( fp, fmt, x[i], y[i], z[i], up[i] ) ; for( i = 0 ; i <= nlines ; i++ ) fprintf( fp, fmt, -y[i], x[i], z[i], up[i] ) ; for( i = 0 ; i <= nlines ; i++ ) fprintf( fp, fmt, -x[i], -y[i], z[i], up[i] ) ; for( i = 0 ; i <= nlines ; i++ ) fprintf( fp, fmt, y[i], -x[i], z[i], up[i] ) ; for( i = 0 ; i <= nlines ; i++ ) fprintf( fp, fmt, x[i], y[i], -z[i], up[i] ) ; for( i = 0 ; i <= nlines ; i++ ) fprintf( fp, fmt, -y[i], x[i], -z[i], up[i] ) ; for( i = 0 ; i <= nlines ; i++ ) fprintf( fp, fmt, -x[i], -y[i], -z[i], up[i] ) ; for( i = 0 ; i <= nlines ; i++ ) fprintf( fp, fmt, y[i], -x[i], -z[i], up[i] ) ; } octo( sigma ) float sigma ; /* 0.0 to 1.0 */ { int i ; float s, t ; for( i = 0 ; i <= nlines ; i++ ) { x[i] = a[i] ; y[i] = b[i] ; z[i] = c[i] ; } s = sigma * 0.5 ; /* 0.0 to 0.5 */ t = 1.0 - sigma * 0.5 ; /* 1.0 to 0.5 */ x[0] = x[9] = s ; z[0] = z[9] = t ; y[1] = s ; z[1] = t ; y[3] = t ; z[3] = s ; x[4] = s ; y[4] = t ; x[6] = t ; y[6] = s ; x[7] = t ; z[7] = s ; } cube( sigma ) float sigma ; /* 0.0 to 1.0 */ { int i ; float s ; for( i = 0 ; i <= nlines ; i++ ) { x[i] = d[i] ; y[i] = e[i] ; z[i] = f[i] ; } s = 1.0 - sigma ; /* 1.0 to 0.0 */ y[0] = y[7] = y[9] = s ; x[1] = x[3] = s ; z[4] = z[6] = s ; }