如何在控制台绘制甜甜圈?

最近发现一个很有意思的东西,在控制台绘制有光照且能转动的甜甜圈,放个原文的链接: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);
            //}
        }
        
    }

}

 

posted @ 2022-10-20 16:43  人间别久不成悲  阅读(35)  评论(0编辑  收藏  举报