Skip to content

Instantly share code, notes, and snippets.

@Hachem-H
Last active August 21, 2023 09:27
Show Gist options
  • Save Hachem-H/0b1b6a1ad15dbb85779af9210373e8fb to your computer and use it in GitHub Desktop.
Save Hachem-H/0b1b6a1ad15dbb85779af9210373e8fb to your computer and use it in GitHub Desktop.
A 3D ASCII-Terminal cube projection.
// gcc -o ASCII-Cube -O2 -DNDEBUG -Wall -Wextra -Werror ASCII-Cube.c -lm
// ./ASCII-Cube
// NOTE: - Resize the terminal to at least 160 columns & 44 rows.
// - This does depend on a terminal which supports ASCII escape codes.
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <math.h>
#define CubeSize 10.f
#define BUFFER_WIDTH 160
#define BUFFER_HEIGHT 44
static float ZBuffer[BUFFER_WIDTH*BUFFER_HEIGHT];
static char OutBuffer[BUFFER_WIDTH*BUFFER_HEIGHT];
static float A = 0.00f;
static float B = 0.00f;
static float C = 0.00f;
static float CalculateX(int i, int j, int k)
{
return j * sin(A) * sin(B) * cos(C) -
k * cos(A) * sin(B) * cos(C) +
j * cos(A) * sin(C) +
k * sin(A) * sin(C) +
i * cos(B) * cos(C);
}
static float CalculateY(int i, int j, int k)
{
return j * cos(A) * cos(C) +
k * sin(A) * cos(C) -
j * sin(A) * sin(B) * sin(C) +
k * cos(A) * sin(B) * sin(C) -
i * cos(B) * sin(C);
}
static float CalculateZ(int i, int j, int k)
{
return k * cos(A) * cos(B) -
j * sin(A) * cos(B) +
i * sin(B);
}
static void ProjectSurface(float cx, float cy, float cz, char character)
{
float x = CalculateX(cx, cy, cz);
float y = CalculateY(cx, cy, cz);
float z = CalculateZ(cx, cy, cz) + BUFFER_HEIGHT - CubeSize;
float zOff = 40;
float invZ = 1/z;
float xOff = CubeSize*2;
int xp = (int)(BUFFER_WIDTH/2 + zOff * invZ * x * 2 - xOff);
int yp = (int)(BUFFER_HEIGHT/2 + zOff * invZ * y);
unsigned int index = xp + yp * BUFFER_WIDTH;
if (index < sizeof(OutBuffer))
if (ZBuffer[index] < invZ)
{
ZBuffer[index] = invZ;
OutBuffer[index] = character;
}
}
int main()
{
printf("\x1b[2J");
while (true)
{
memset(OutBuffer, ' ', sizeof(OutBuffer));
memset(ZBuffer, 0x0, sizeof(ZBuffer));
for (float x = -CubeSize; x < CubeSize; x++)
for (float y = -CubeSize; y < CubeSize; y++)
{
ProjectSurface( x, y, -CubeSize, '.');
ProjectSurface( CubeSize, y, x, '$');
ProjectSurface(-CubeSize, y, -x, '~');
ProjectSurface(-x, y, CubeSize, '@');
ProjectSurface( x, -CubeSize, -y, ';');
}
printf("\x1b[H");
for (unsigned int i = 0; i < sizeof(OutBuffer); i++)
putchar(i % BUFFER_WIDTH ? OutBuffer[i] : '\n');
A += 0.005f;
B += 0.005f;
usleep(2000);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment