/* hedra.c (isu.c) - Don Yang (uguu.org) gcc -lm hedra.c lclint 2.5m - no code errors found (yay!) 12/04/00 */ #include #include #include #include #define DEFAULT_WIDTH 79 #define DEFAULT_HEIGHT 23 #define MAX_WIDTH 256 #define MAX_HEIGHT 256 #define MIN_WIDTH 20 #define MIN_HEIGHT 20 #define STEP_COUNT 128 /* theta (degrees), phi (degrees) */ static int *vertex, vertex_cube[] = { 0, 45, 90, 45, 180, 45, 270, 45, 0,135, 90,135, 180,135, 270,135, 0,0}, vertex_octa[] = { 0, 90, 90, 90, 180, 90, 270, 90, 0,180, 0,360, 0,0}, vertex_tetra[] = { 0,180, 0, 60, 120, 60, 240, 60, 0,0}; static int *edge, edge_cross[] = {0,2, 1,3, 4,5, 0,0}, edge_cube[] = {0,1, 1,2, 2,3, 3,0, 4,5, 5,6, 6,7, 7,4, 0,4, 1,5, 2,6, 3,7, 0,0}, edge_octa[] = {0,4, 1,4, 2,4, 3,4, 0,5, 1,5, 2,5, 3,5, 0,1, 1,2, 2,3, 3,0, 0,0}, edge_tetra[] = {0,1, 0,2, 0,3, 1,2, 2,3, 3,1, 0,0}; static double point[16][3]; static double conv; static int i, j, u, width, height, scale, rotatex, rotatey; static char screen[MAX_HEIGHT][MAX_WIDTH]; /***************************************************************** convert */ static void convert(int theta, int phi, double *x, double *y, double *z) { double t, p, r; r = sin(p = phi * conv); *z = cos(p); *x = r * cos(t = (theta + rotatey) * conv) * 1.5; *y = r * sin(t); r = rotatex * conv; t = cos(r) * *y - sin(r) * *z; *z = sin(r) * *z + cos(r) * *y; *y = t; } /* convert() */ /******************************************************************** line */ static void line(double xi, double yi, double zi, double xf, double yf, double zf) { for(u = 0; u < STEP_COUNT; u++) { screen [ (int)((yi + (u * (yf - yi)) / STEP_COUNT) * scale + height / 2) ] [ (int)((xi + (u * (xf - xi)) / STEP_COUNT) * scale + width / 2) ] = (zi + (u * (zf - zi)) / STEP_COUNT) > 0 ? 'x' : '.'; } } /* line() */ /******************************************************************** main */ int main(int argc, char **argv) { /* Set parameters */ width = argc > 1 ? atoi(argv[1]) : DEFAULT_WIDTH; height = argc > 2 ? atoi(argv[2]) : DEFAULT_HEIGHT; if( width < MIN_WIDTH || width > MAX_WIDTH || height < MIN_HEIGHT || height > MAX_HEIGHT ) return 1; scale = (width > height ? height : width) / 2; srand((unsigned)time(NULL)); rotatex = rand() % 360; rotatey = rand() % 360; conv = atan2(0, -1) / 180; /* Clear screen */ for(i = 0; i < height; i++) for(j = 0; j < width; screen[i][j++] = ' '); /* Render */ switch( rand() % 4 ) { case 0: vertex = vertex_tetra; edge = edge_tetra; break; case 1: vertex = vertex_cube; edge = edge_cube; break; case 2: vertex = vertex_octa; edge = edge_octa; break; default: vertex = vertex_octa; edge = edge_cross; break; } for(i = 0; vertex[i] > 0 || vertex[i + 1] > 0; i += 2) { convert(vertex[i], vertex[i + 1], &point[i / 2][0], &point[i / 2][1], &point[i / 2][2]); } for(i = 0; edge[i] != edge[i + 1]; i += 2) { line(point[edge[i]][0], point[edge[i]][1], point[edge[i]][2], point[edge[i + 1]][0], point[edge[i + 1]][1], point[edge[i + 1]][2]); } /* Display */ for(i = 0; i < height; i++) { for(j = 0; j < width; putchar(screen[i][j++])); (void)putchar('\n'); } return 0; } /* main() */