esp32搭配oled显示图形学正十二面体
...
esp32搭配oled显示图形学正十二面体
代码如下:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <math.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET 4
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const float PHI = (1.0 + sqrt(5.0)) / 2.0;
const float SCALE = 12.0;
float vertices[20][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},
{0, -1 / PHI, -PHI},
{0, -1 / PHI, PHI},
{0, 1 / PHI, -PHI},
{0, 1 / PHI, PHI},
{-1 / PHI, -PHI, 0},
{-1 / PHI, PHI, 0},
{1 / PHI, -PHI, 0},
{1 / PHI, PHI, 0},
{-PHI, 0, -1 / PHI},
{PHI, 0, -1 / PHI},
{-PHI, 0, 1 / PHI},
{PHI, 0, 1 / PHI}};
int edges[30][2];
int edgeCount = 0;
float angleX = 0.0;
float angleY = 0.0;
float angleZ = 0.0;
float dist2(float *a, float *b)
{
return (a[0] - b[0]) * (a[0] - b[0]) +
(a[1] - b[1]) * (a[1] - b[1]) +
(a[2] - b[2]) * (a[2] - b[2]);
}
void generateEdges()
{
float threshold = 3.0;
edgeCount = 0;
for (int i = 0; i < 20; i++)
{
for (int j = i + 1; j < 20; j++)
{
float d = dist2(vertices[i], vertices[j]);
if (d < threshold)
{
if (edgeCount < 30)
{
edges[edgeCount][0] = i;
edges[edgeCount][1] = j;
edgeCount++;
}
}
}
}
}
void drawDodecahedron()
{
int projected[20][2];
for (int i = 0; i < 20; i++)
{
float x = vertices[i][0] * SCALE;
float y = vertices[i][1] * SCALE;
float z = vertices[i][2] * SCALE;
float y1 = y * cos(angleX) - z * sin(angleX);
float z1 = y * sin(angleX) + z * cos(angleX);
float x2 = x * cos(angleY) + z1 * sin(angleY);
float z2 = -x * sin(angleY) + z1 * cos(angleY);
float x3 = x2 * cos(angleZ) - y1 * sin(angleZ);
float y3 = x2 * sin(angleZ) + y1 * cos(angleZ);
float distance = 50.0;
float factor = distance / (distance + z2);
int px = (int)(x3 * factor + SCREEN_WIDTH / 2);
int py = (int)(y3 * factor + SCREEN_HEIGHT / 2);
projected[i][0] = px;
projected[i][1] = py;
}
for (int e = 0; e < edgeCount; e++)
{
int p1 = edges[e][0];
int p2 = edges[e][1];
display.drawLine(projected[p1][0], projected[p1][1],
projected[p2][0], projected[p2][1],
SSD1306_WHITE);
}
}
void setup()
{
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
{
for (;;)
;
}
display.clearDisplay();
generateEdges();
}
void loop()
{
display.clearDisplay();
drawDodecahedron();
display.display();
angleX += 0.02;
angleY += 0.03;
angleZ += 0.015;
delay(40);
}