ΠΡ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠΈΡΡΠ΅ΠΌΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠΎΠ΅ΡΠΈΡΡΠ΅Ρ Π³ΠΎΠ»ΠΎΠ³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΡΡ Π²ΡΠ΅Π»Π΅Π½Π½ΡΡ Π² 3D-ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ LED-ΠΌΠ°ΡΡΠΈΡΡ ΠΈ ΡΡΡΠ΅ΠΊΡ POV!
ΠΠΎΠ»ΠΎΠ³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΏΡΠΎΠ΅ΠΊΡΠΎΡ:
cpp
#include <avr/pgmspace.h>
#define RESOLUTION 16
#define ANGLE_STEPS 64
#define DEPTH_LAYERS 8
// 3D-ΠΎΠ±ΡΠ΅ΠΊΡΡ (Π³ΠΎΠ»ΠΎΠ³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π΄Π°Π½Π½ΡΠ΅)
struct Hologram {
int8_t vertices[RESOLUTION][3]; // x, y, z ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΡ
uint8_t color[RESOLUTION];
uint8_t vertexCount;
};
Hologram universeHologram;
uint8_t hologramBuffer[ANGLE_STEPS][RESOLUTION];
// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π³Π°Π»Π°ΠΊΡΠΈΠΊΠΈ Π² Π³ΠΎΠ»ΠΎΠ³ΡΠ°ΠΌΠΌΠ΅
void createGalaxyHologram() {
universeHologram.vertexCount = RESOLUTION;
for (uint8_t i = 0; i < RESOLUTION; i++) {
// Π‘ΠΏΠΈΡΠ°Π»ΡΠ½Π°Ρ Π³Π°Π»Π°ΠΊΡΠΈΠΊΠ°
float angle = i * 22.5 * 3.14159 / 180;
float radius = (i / (float)RESOLUTION) * 8;
universeHologram.vertices[i][0] = radius * cos(angle) * 2;
universeHologram.vertices[i][1] = radius * sin(angle) * 2;
universeHologram.vertices[i][2] = sin(angle * 3) * 3;
universeHologram.color[i] = 128 + radius * 16;
}
}
// 3D-Π²ΡΠ°ΡΠ΅Π½ΠΈΠ΅ (ΠΌΠ°ΡΡΠΈΡΠ° ΠΏΠΎΠ²ΠΎΡΠΎΡΠ°)
void rotateHologram(uint16_t angleX, uint16_t angleY, uint16_t angleZ) {
int16_t cosX = pgm_read_word(&cosTable[angleX]);
int16_t sinX = pgm_read_word(&sinTable[angleX]);
int16_t cosY = pgm_read_word(&cosTable[angleY]);
int16_t sinY = pgm_read_word(&sinTable[angleY]);
int16_t cosZ = pgm_read_word(&cosTable[angleZ]);
int16_t sinZ = pgm_read_word(&sinTable[angleZ]);
for (uint8_t i = 0; i < universeHologram.vertexCount; i++) {
int8_t x = universeHologram.vertices[i][0];
int8_t y = universeHologram.vertices[i][1];
int8_t z = universeHologram.vertices[i][2];
// ΠΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ X
int16_t y1 = (y * cosX - z * sinX) / 256;
int16_t z1 = (y * sinX + z * cosX) / 256;
// ΠΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ Y
int16_t x1 = (x * cosY + z1 * sinY) / 256;
int16_t z2 = (-x * sinY + z1 * cosY) / 256;
// ΠΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ Z
int16_t x2 = (x1 * cosZ - y1 * sinZ) / 256;
int16_t y2 = (x1 * sinZ + y1 * cosZ) / 256;
universeHologram.vertices[i][0] = x2;
universeHologram.vertices[i][1] = y2;
universeHologram.vertices[i][2] = z2;
}
}
// ΠΡΠΎΠ΅ΠΊΡΠΈΡ 3D Π² 2D (ΠΏΠ΅ΡΡΠΏΠ΅ΠΊΡΠΈΠ²Π½Π°Ρ)
void projectHologram() {
// ΠΡΠΈΡΠ°Π΅ΠΌ Π±ΡΡΠ΅Ρ
memset(hologramBuffer, 0, sizeof(hologramBuffer));
for (uint8_t angle = 0; angle < ANGLE_STEPS; angle++) {
uint16_t viewAngle = angle * 360 / ANGLE_STEPS;
for (uint8_t i = 0; i < universeHologram.vertexCount; i++) {
int8_t x = universeHologram.vertices[i][0];
int8_t y = universeHologram.vertices[i][1];
int8_t z = universeHologram.vertices[i][2];
// ΠΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΡΠΎΡΠΊΠΈ Π΄Π»Ρ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ ΡΠ³Π»Π° ΠΎΠ±Π·ΠΎΡΠ°
int16_t rx = (x * cos(viewAngle) - z * sin(viewAngle)) / 256;
int16_t rz = (x * sin(viewAngle) + z * cos(viewAngle)) / 256;
// ΠΠ΅ΡΡΠΏΠ΅ΠΊΡΠΈΠ²Π½Π°Ρ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡ
int16_t fov = 64;
int16_t scale = fov / (rz + fov + 1);
uint8_t screenX = 8 + (rx * scale) / 32;
uint8_t screenY = 8 + (y * scale) / 32;
if (screenX < RESOLUTION && screenY < RESOLUTION) {
hologramBuffer[angle][screenX] = universeHologram.color[i];
}
}
}
}
// ΠΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π³ΠΎΠ»ΠΎΠ³ΡΠ°ΠΌΠΌΡ Π½Π° LED-ΠΌΠ°ΡΡΠΈΡΠ΅
void renderHologram() {
static uint8_t currentAngle = 0;
currentAngle = (currentAngle + 1) % ANGLE_STEPS;
clearScreen();
// Π ΠΈΡΡΠ΅ΠΌ 3D-ΠΏΡΠΎΠ΅ΠΊΡΠΈΡ
for (uint8_t x = 0; x < RESOLUTION; x++) {
uint8_t intensity = hologramBuffer[currentAngle][x];
if (intensity > 0) {
drawPixel(x, 8 + intensity / 16, intensity > 100);
}
}
// Π ΠΈΡΡΠ΅ΠΌ Π»ΠΈΠ½ΠΈΠΈ Π³Π»ΡΠ±ΠΈΠ½Ρ
for (uint8_t i = 0; i < 8; i++) {
drawPixel(i, 0, 1);
drawPixel(RESOLUTION - 1 - i, RESOLUTION - 1, 1);
}
updateDisplay();
}
// ΠΠΎΠ»ΠΎΠ³ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡ (ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° 3D-Π΄Π°Π½Π½ΡΡ
)
void holographicProcessor() {
// ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π³ΠΎΠ»ΠΎΠ³ΡΠ°ΠΌΠΌΡ
static uint16_t angleX = 0;
static uint16_t angleY = 0;
static uint16_t angleZ = 0;
angleX = (angleX + 1) % 360;
angleY = (angleY + 2) % 360;
angleZ = (angleZ + 3) % 360;
rotateHologram(angleX, angleY, angleZ);
projectHologram();
}
void setup() {
initLEDMatrix();
createGalaxyHologram();
Serial.println("π ΠΠΠΠΠΠ ΠΠ€ΠΠ§ΠΠ‘ΠΠΠ― ΠΠ‘ΠΠΠΠΠΠΠ― ΠΠΠ’ΠΠΠΠ ΠΠΠΠΠ");
}
void loop() {
holographicProcessor();
renderHologram();
delay(50);
}