/** * ASCII spinning glboe */ #include "colors.h" #include #include #include #include #include #include #include const double GOLDEN_RATIO = 1.6180339887498948482045868343656381; const int NUM_WAVES = 7; const double OFFSETS[2*NUM_WAVES] = { 0.5459919526, 0.6072439135, 0.6217563193, 0.5444045324, 0.8923452588, 0.4626828607, 0.9422234679, 0.7870886548, 0.7425605127, 0.1510923405, 0.3889282293, 0.3730024274, 0.1450487012, 0.9051931355, }; const double AMPLITUDES[NUM_WAVES] = { //0.9, 0.81, 0.729, 0.6561, 0.59049, 0.531441, 0.4782969 0.83, 0.6889, 0.571787, 0.47458321, 0.3939040643, 0.326940373369, 0.27136050989627 }; static double hillnoise(double x, double y) { double noise = 0; double sigma = 0; for (int i = 0; i < NUM_WAVES; i++) { // Rotate coordinates double rotation = fmod(((float)i)*GOLDEN_RATIO, 1.0)*2.0*M_PI; double u = x*cos(rotation) - y*sin(rotation); double v = -x*sin(rotation) - y*cos(rotation); double size = AMPLITUDES[i]; double offsetx = OFFSETS[2*i]; double offsety = OFFSETS[2*i+1]; noise += (size/2.)*(sin(u/size + offsetx) + sin(v/size + offsety)); sigma += size*size; } sigma = sqrt(sigma)/2.; noise /= 2.*sigma; return (0.5*(noise < 0 ? -1. : 1.)*sqrt(1 - exp(-2./M_PI * noise*noise)) + 0.5); } static double mix(double a, double b, double amount) { return (1.-amount)*a + amount*b; } void draw_stars() { int rows,cols; getmaxyx(stdscr,rows,cols); attron(COLOR_PAIR(WHITE)); for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { double n = hillnoise(r*100,c*200); if (n > .8) { mvaddch(r,c,n > .9 ? '*' : '.'); } } } attroff(COLOR_PAIR(WHITE)); } void draw_globe(double t, double zoom) { int rows,cols; getmaxyx(stdscr,rows,cols); double rotation = t * (2*M_PI)/10. + M_PI; const double rho = rows/2.; for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { double y = (c - cols/2) * 0.5 / zoom; double z = (r - rows/2) * 1.0 / zoom; double x = sqrt(rho*rho - z*z - y*y); if (z*z + y*y > rho*rho) { continue; } double theta = atan2(z, sqrt(x*x + y*y)); double phi = fmod(atan2(y, x) + rotation, 2.*M_PI); double elevation = hillnoise(theta*5., phi*5.); double clouds = hillnoise(theta*5., phi*5. - 1.*rotation - 100.); int color; int ch; if ((fabs(z)/rho) > .9) { elevation = elevation + mix(.0, 1., 10.*(fabs(z)/rho - .9)) > .6 ? 1. : 0.; } if (clouds < .4) { ch = (clouds < .3 ? '0' : '%') | A_BOLD; color = COLOR_PAIR(WHITE); } else if (elevation < .55) { ch = '~'; color = COLOR_PAIR(BLUE); } else if (elevation < .6) { ch = ':'; color = COLOR_PAIR(YELLOW); } else if (elevation < .85) { ch = 'S'; color = COLOR_PAIR(GREEN); } else { ch = '#'; color = COLOR_PAIR(WHITE); } attron(color); mvaddch(r,c,ch); attroff(color); } } } void draw_scorch(double t, double zoom, int *targetr, int *targetc) { int rows,cols; getmaxyx(stdscr,rows,cols); double rotation = t * (2*M_PI)/10. + M_PI*1.4; const double rho = rows/2.; double theta = M_PI/2*1.1; double phi = M_PI + rotation; double x = rho*sin(theta)*cos(phi); double y = rho*sin(theta)*sin(phi); double z = rho*cos(theta); int r = z / (1.0/zoom) + rows/2; int c = y / (.5/zoom) + cols/2; *targetr = r; *targetc = c; attron(COLOR_PAIR(BLACK) | A_BOLD); mvprintw(r-1,c-1,"****"); mvprintw(r,c-2, "******"); mvprintw(r+1,c-1,"****"); attroff(COLOR_PAIR(BLACK) | A_BOLD); } void draw_target(double t, double zoom, int *targetr, int *targetc) { int rows,cols; getmaxyx(stdscr,rows,cols); double rotation = t * (2*M_PI)/10. + M_PI*1.4; const double rho = rows/2.; double theta = M_PI/2*1.1; double phi = M_PI + rotation; double x = rho*sin(theta)*cos(phi); double y = rho*sin(theta)*sin(phi); double z = rho*cos(theta); int r = z / (1.0/zoom) + rows/2; int c = y / (.5/zoom) + cols/2; *targetr = r; *targetc = c; if (x < 0) { attron(COLOR_PAIR(YELLOW)); mvaddch(r,c, '*' | A_BOLD); attroff(COLOR_PAIR(YELLOW)); } double wobble = t > 2.5 ? 0. : 2.5 - t; if (wobble > .01) { r = mix(r, rows*hillnoise(784,5.*t), wobble); c = mix(c, cols*hillnoise(-784,5.*t), wobble); } int attr = COLOR_PAIR(RED); attron(attr); mvaddch(r-1,c-2,ACS_ULCORNER | A_BOLD); mvaddch(r-1,c-1,ACS_HLINE | A_BOLD); //mvaddch(r-1,c-0,ACS_HLINE | A_BOLD); mvaddch(r-1,c+1,ACS_HLINE | A_BOLD); mvaddch(r-1,c+2,ACS_URCORNER | A_BOLD); //mvaddch(r-0,c+2,ACS_VLINE | A_BOLD); mvaddch(r+1,c+2,ACS_LRCORNER | A_BOLD); mvaddch(r+1,c+1,ACS_HLINE | A_BOLD); //mvaddch(r+1,c+0,ACS_HLINE | A_BOLD); mvaddch(r+1,c-1,ACS_HLINE | A_BOLD); mvaddch(r+1,c-2,ACS_LLCORNER | A_BOLD); //mvaddch(r+0,c-2,ACS_VLINE | A_BOLD); mvaddch(r,c,'X' | A_BOLD); attroff(attr); }