#include <U8g2lib.h> // Biblioteca U8g2
// Inicialização do display (I2C)
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
int points[8][2]; // Oito pontos 2D para o cubo
// Oito pontos 3D definidos para o cubo
int orig_points[8][3] = {
{ -1, -1, 1 },
{ 1, -1, 1 },
{ 1, 1, 1 },
{ -1, 1, 1 },
{ -1, -1, -1 },
{ 1, -1, -1 },
{ 1, 1, -1 },
{ -1, 1, -1 }
};
float rotated_3d_points[8][3]; // Oito pontos 3D rotacionados em torno do eixo Y
float angle_deg = 0.0; // Rotação em torno do eixo Y
float z_offset = -4.0; // Deslocamento no eixo Z
float cube_size = 32.0; // Tamanho do cubo (multiplicador)
float time_frame = 0; // Valor de tempo sempre crescente
// Variáveis para movimentação do cubo
float pos_x = 64; // Posição X inicial do cubo (meio da tela)
float pos_y = 32; // Posição Y inicial do cubo (meio da tela)
float vel_x = 1.5; // Velocidade X do cubo
float vel_y = 1.0; // Velocidade Y do cubo
void setup() {
u8g2.begin(); // Inicializa o display
u8g2.setDrawColor(1); // Define a cor para branco
}
void loop() {
time_frame++; // Aumenta o valor do tempo em 1 frame
angle_deg += 5; // Aumenta o ângulo de rotação
if (angle_deg >= 360) {
angle_deg = 0;
}
// Movimentação do cubo
pos_x += vel_x;
pos_y += vel_y;
// Verifica colisão com as bordas e corrige a posição se necessário
if (pos_x - (cube_size / 2) + 4 <= 0 || pos_x + (cube_size / 2) + 4 >= 128) {
vel_x = -vel_x; // Inverte a direção no eixo X
pos_x = constrain(pos_x, (cube_size / 2), 128 - (cube_size / 2));
}
if (pos_y - (cube_size / 2) + 4 <= 0 || pos_y + (cube_size / 2) >= 64) {
vel_y = -vel_y; // Inverte a direção no eixo Y
pos_y = constrain(pos_y, cube_size / 2, 64 - (cube_size / 2));
}
// Calcula os pontos
for (int i = 0; i < 8; i++) {
// Rotaciona os pontos 3D em torno do eixo Y (rotacionando as posições X e Z)
rotated_3d_points[i][0] = orig_points[i][0]
* cos(radians(angle_deg))
- orig_points[i][2]
* sin(radians(angle_deg));
rotated_3d_points[i][1] = orig_points[i][1];
rotated_3d_points[i][2] = orig_points[i][0]
* sin(radians(angle_deg))
+ orig_points[i][2]
* cos(radians(angle_deg))
+ z_offset;
// Projeta os pontos 3D no espaço 2D com divisão de perspectiva - 2D x = x/z, 2D y = y/z
points[i][0] = round(pos_x + rotated_3d_points[i][0] / rotated_3d_points[i][2] * cube_size);
points[i][1] = round(pos_y + rotated_3d_points[i][1] / rotated_3d_points[i][2] * cube_size);
}
u8g2.clearBuffer(); // Limpa o buffer do display
// Conecta as linhas entre os pontos individuais para formar o cubo
u8g2.drawLine(points[0][0], points[0][1], points[1][0], points[1][1]); // Conecta pontos 0-1
u8g2.drawLine(points[1][0], points[1][1], points[2][0], points[2][1]); // Conecta pontos 1-2
u8g2.drawLine(points[2][0], points[2][1], points[3][0], points[3][1]); // Conecta pontos 2-3
u8g2.drawLine(points[3][0], points[3][1], points[0][0], points[0][1]); // Conecta pontos 3-0
u8g2.drawLine(points[4][0], points[4][1], points[5][0], points[5][1]); // Conecta pontos 4-5
u8g2.drawLine(points[5][0], points[5][1], points[6][0], points[6][1]); // Conecta pontos 5-6
u8g2.drawLine(points[6][0], points[6][1], points[7][0], points[7][1]); // Conecta pontos 6-7
u8g2.drawLine(points[7][0], points[7][1], points[4][0], points[4][1]); // Conecta pontos 7-4
u8g2.drawLine(points[0][0], points[0][1], points[4][0], points[4][1]); // Conecta pontos 0-4
u8g2.drawLine(points[1][0], points[1][1], points[5][0], points[5][1]); // Conecta pontos 1-5
u8g2.drawLine(points[2][0], points[2][1], points[6][0], points[6][1]); // Conecta pontos 2-6
u8g2.drawLine(points[3][0], points[3][1], points[7][0], points[7][1]); // Conecta pontos 3-7
u8g2.sendBuffer(); // Envia o buffer para o display
delay(10); // Pequeno atraso para suavizar a animação
}