1
0

initial commit

This commit is contained in:
Rokas Puzonas 2023-05-11 21:23:10 +03:00
commit 8319d127a5
3 changed files with 80 additions and 0 deletions

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Spinning donut
Source: https://www.a1k0n.net/2011/07/20/donut-math.html

BIN
donut Executable file

Binary file not shown.

77
donut.c Normal file
View File

@ -0,0 +1,77 @@
#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;
}
}