旋转的立方体
#include <cstdint>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <thread>
using namespace std;float angleX = .0f;
float angleY = .0f;
float angleZ = .0f;
constexpr int32_t width = 170;
constexpr int32_t height = 40;
constexpr int32_t cubeWidth = 10;
constexpr int32_t cubeHeight = 10;
char buffer[width * height];
float zIndex[width * height];
float distanceFromCarmera = 100.0f;
char shadowChar[] = ".,:;irssXAMG@$$";struct Position {float x;float y;float z;
};struct Vector {float x;float y;float z;Vector operator-(const Vector& obj) {return Vector{x - obj.x, y - obj.y, z - obj.z};}float operator*(const Vector& obj) {return x * obj.x + y * obj.y + z * obj.z;}Vector Normalize() {float len = sqrt(x * x + y * y + z * z);if (len == 0) return {.0f, .0f, .0f};return Vector{ x / len, y / len, z / len };}
};Vector light{-5.0, 3.0, 2.0};float CalculatePositionX(const Position& pos) {return cos(angleX) * (pos.x * cos(angleY) - sin(angleY) * (pos.z * cos(angleZ) - pos.y * sin(angleZ))) + sin(angleX) * (pos.y * cos(angleZ) + pos.z * sin(angleZ));
}float CalculatePositionY(const Position& pos) {return cos(angleX) * (pos.y * cos(angleZ) + pos.z * sin(angleZ)) - sin(angleX) * (pos.x * cos(angleY) - sin(angleY) * (pos.z * cos(angleZ) - pos.y * sin(angleZ)));
}float CalculatePositionZ(const Position& pos) {return pos.x * sin(angleY) + cos(angleY) * (pos.z * cos(angleZ) - pos.y * sin(angleZ));
}void CalculatePosition(const Position& pos, const Position& normal) {float x = CalculatePositionX(pos);float y = CalculatePositionY(pos);float z = CalculatePositionZ(pos) + distanceFromCarmera;float normalX = CalculatePositionX(normal);float normalY = CalculatePositionY(normal);float normalZ = CalculatePositionZ(normal);Vector cur {x, y, z};Vector lightDir = (light - cur).Normalize();float factor = lightDir * Vector{normalX, normalY, normalZ};int32_t shadowIndex = (int32_t)((1.0 - factor) * (sizeof(shadowChar) - 1));if (z == 0) return;// 映射到buffer中的位置int32_t col = (int32_t)(width / 2 + 80 * x * 2 / z);int32_t row = (int32_t)(height / 2 + 80 * y / z);int32_t index = col + width * row;if (index < width * height && index >= 0) {if (z < zIndex[index]) {buffer[index] = shadowChar[shadowIndex];// buffer[index] = '#';zIndex[index] = z;}}
}int main() {while(true) {memset(buffer, ' ', width * height * sizeof(char));memset(zIndex, 600, width * height * sizeof(float));printf("\033[H");printf("\033[J");for (float x = -cubeWidth; x < cubeWidth; x += 0.6) {for (float y = -cubeHeight; y < cubeHeight; y += 0.6) {CalculatePosition({x, y, (float)-cubeWidth}, {.0f, .0f, -1.0f});CalculatePosition({x, y, (float)cubeWidth}, {.0f, .0f, 1.0f});CalculatePosition({(float)cubeWidth, x, y}, {1.0f, .0f, .0f});CalculatePosition({-(float)cubeWidth, x, y}, {-1.0f, .0f, .0f});CalculatePosition({x, (float)cubeWidth, y}, {.0f, 1.0f, .0f});CalculatePosition({x, -(float)cubeWidth, y}, {.0f, -1.0f, .0f});}}for (int32_t i = 0; i < width * height; i++) {putchar((i % width) ? buffer[i] : '\n');}this_thread::sleep_for(0.008s);angleX += 0.005;angleY += 0.005;angleZ += 0.003;}return 0;
}