如何在控制台绘制甜甜圈?
最近发现一个很有意思的东西,在控制台绘制有光照且能转动的甜甜圈,放个原文的链接:https://www.a1k0n.net/2011/07/20/donut-math.html
具体的代码如下:
#include <iostream> #include <vector> #include <Windows.h> #include <math.h> #define repf(i,a,b,s) for (float i=a;i<b;i+=s) using namespace std; const float theta_spacing = 0.07; const float phi_spacing = 0.02; const float R1 = 0.8; const float R2 = 2; const float K2 = 8; const float screen_width = 80; const float screen_height = 80; const float K1 = screen_width * K2 * 3 / (8 * (R1 + R2)); char pix[] = { '.','\,','-',' ~',':',';','=','!','*','#','$','@' }; void render_frame(float A, float B) { float cosA = cos(A), sinA = sin(A); float cosB = cos(B), sinB = sin(B); vector<vector<float>> zbuffer(screen_width, vector<float>(screen_width, 0)); vector<vector<char>> output(screen_width, vector<char>(screen_width, ' ')); for (float theta = 0; theta < 2 * pi; theta += theta_spacing) { float costheta = cos(theta), sintheta = sin(theta); for (float phi = 0; phi < 2 * pi; phi += phi_spacing) { float cosphi = cos(phi), sinphi = sin(phi); float circlex = R2 + R1 * costheta; float circley = R1 * sintheta; float x = circlex * (cosB * cosphi + sinA * sinB * sinphi) - circley * cosA * sinB; float y = circlex * (sinB * cosphi - sinA * cosB * sinphi) + circley * cosA * cosB; float z = K2 + cosA * circlex * sinphi + circley * sinA; float ooz = 1 / z; int xp = (int)(screen_width / 2 + K1 * ooz * x)+5; int yp = (int)(screen_height / 2 - K1 * ooz * y)+5; float L = cosphi * costheta * sinB - cosA * costheta * sinphi - sinA * sintheta + cosB * (cosA * sintheta - costheta * sinA * sinphi); if (L > 0) { if (ooz > zbuffer[xp][yp]) { zbuffer[xp][yp] = ooz; int luminance_index = L * 8; output[xp][yp] = pix[luminance_index]; } } } } //printf("\x1b[H"); for (int j = 0; j < screen_height; j++) { for (int i = 0; i < screen_width; i++) { //cout<<(output[i][j]); putchar(output[i][j]); } /*cout << endl;*/ putchar('\n'); } } HANDLE hOutput; COORD coord = { 0,0 }; int main() { hOutput = GetStdHandle(STD_OUTPUT_HANDLE); while (1) { repf(a, 0, 2 * pi, pi / 100) { /*repf(b, 0, 2 * pi, pi / 20) {*/ Sleep(5); CONSOLE_CURSOR_INFO cursor_info = { 1, 0 }; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); SetConsoleCursorPosition(hOutput, coord); render_frame(a, 1); //} } } }