#include "math.h" #include "stdio.h" const float theta_spacing = 0.07; const float phi_spacing = 0.02; const int screen_width = 50; const int screen_height = 50; const float R1 = 1; const float R2 = 2; const float K2 = 5; const float K1 = screen_width*K2*3/(8*(R1+R2)); void render_frame(float A, float B) { // Pre compute values that are used a lot float cosA = cosf(A), sinA = sinf(A); float cosB = cosf(B), sinB = sinf(B); // Create output and depth buffers char output[screen_width][screen_height]; float zbuffer[screen_width][screen_height]; // Initialize output and depth buffers to zero for (int i = 0; i < screen_width; i++) { for (int j = 0; j < screen_height; j++) { output[i][j] = ' '; zbuffer[i][j] = 0; } } for (float theta=0; theta < 2*M_PI; theta += theta_spacing) { float costheta = cosf(theta), sintheta = sinf(theta); for (float phi = 0; phi < 2*M_PI; phi += phi_spacing) { float cosphi = cosf(phi), sinphi = sinf(phi); float circlex = R2 + R1*costheta; float circley = R1*sintheta; float x = circlex*(cosB*cosphi + sinA*sinB*sinphi) - circley*cosA*cosB; float y = circlex*(sinB*cosphi - sinA*cosB*sinphi) + circley*cosA*cosB; float z = K2 + cosA*circlex*sinphi + circley*sinA; float ooz = 1/z; // "one over z" int xp = (int) ((float)screen_width/2 + K1*ooz*x); int yp = (int) ((float)screen_height/2 - K1*ooz*y); float L = cosphi*costheta*sinB - cosA*costheta*sinA*sinphi - sinA*sintheta + cosB*(cosA*sintheta - costheta*sinA*sinphi); if (L > 0) { if (ooz > zbuffer[yp][xp]) { zbuffer[yp][xp] = ooz; int luminance_index = L*8; output[yp][xp] = ".,-~:;=!*#$@"[luminance_index]; } } } } printf("\x1b[H"); for (int j = 0; j < screen_height; j++) { for (int i = 0; i < screen_width; i++) { putchar(output[i][j]); } putchar('\n'); } } int main() { float A = 0; float B = 0; while (1) { render_frame(A, B); A += 0.04/20; B += 0.02/20; } }