a couple of rotating cubes - using the SSD1306 module from Adafruit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SPI.h> | |
#include <Wire.h> | |
#include <Adafruit_GFX.h> | |
#include <Adafruit_SSD1306.h> | |
#include <math.h> | |
#define CAM_F 120 | |
#define OLED_DC 6 | |
#define OLED_CS 7 | |
#define OLED_RESET 8 | |
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS); | |
typedef struct { | |
int x; | |
int y; | |
int z; | |
} point3D_type, *point3D; | |
double theta = 0.0; | |
double sinTheta; | |
double cosTheta; | |
void advanceRotation() { | |
theta += 0.1; | |
if (theta >= (2 * 3.1417)) { | |
theta = 0.0; | |
} | |
// we re-use these a LOT | |
sinTheta = sin(theta); | |
cosTheta = cos(theta); | |
} | |
int xpos = 0; | |
int ypos = 0; | |
int zpos = 0; | |
int dx = 1; | |
int dy = 2; | |
int dz = 3; | |
void advancePosition() { | |
xpos += dx; | |
ypos += dy; | |
zpos += dz; | |
if (xpos >= 64 || xpos <= -64) { | |
dx *= -1; | |
} | |
if (ypos >= 32 || ypos <= -32) { | |
dy *= -1; | |
} | |
if (zpos >= 32 || zpos <= -32) { | |
dz *= -1; | |
} | |
} | |
void drawProjectedLine(point3D_type from, point3D_type to) { | |
/* apply camera transform */ | |
from.z += CAM_F; | |
to.z += CAM_F; | |
int x1_2D = 64 + (int)(((double)from.x / (double)from.z) * CAM_F); | |
int y1_2D = 32 + (int)(((double)from.y / (double)from.z) * CAM_F); | |
int x2_2D = 64 + (int)(((double)to.x / (double)to.z) * CAM_F); | |
int y2_2D = 32 + (int)(((double)to.y / (double)to.z) * CAM_F); | |
/* take projected positions and draw on screen */ | |
display.drawLine(x1_2D, y1_2D, x2_2D, y2_2D, WHITE); | |
} | |
void rotateAndTranslate(point3D p, int x, int y, int z) { | |
int new_x = (p->x * cosTheta) + (p->z * sinTheta) + (x); | |
int new_y = (p->y) + (y); | |
int new_z = (-(p->x) * sinTheta) + (p->z * cosTheta) + z; | |
p->x = new_x; | |
p->y = new_y; | |
p->z = new_z; | |
} | |
// draw a cube centered on the point (x,y,z) with sides of length w | |
void drawCube(int x, int y, int z, int w) { | |
int r = w / 2; // not sure how to abreviate half-of-width; | |
// variables we'll use to create our sides | |
point3D_type p0; | |
point3D_type p1; | |
point3D_type p2; | |
point3D_type p3; | |
point3D_type p4; | |
point3D_type p5; | |
point3D_type p6; | |
point3D_type p7; | |
p0 = { -r, r, -r }; | |
p1 = { r, r, -r }; | |
p2 = { -r, -r, -r }; | |
p3 = { r, -r, -r }; | |
p4 = { -r, r, r }; | |
p5 = { r, r, r }; | |
p6 = { -r, -r, r }; | |
p7 = { r, -r, r }; | |
rotateAndTranslate(&p0, x, y, z); | |
rotateAndTranslate(&p1, x, y, z); | |
rotateAndTranslate(&p2, x, y, z); | |
rotateAndTranslate(&p3, x, y, z); | |
rotateAndTranslate(&p4, x, y, z); | |
rotateAndTranslate(&p5, x, y, z); | |
rotateAndTranslate(&p6, x, y, z); | |
rotateAndTranslate(&p7, x, y, z); | |
drawProjectedLine(p0, p1); | |
drawProjectedLine(p0, p2); | |
drawProjectedLine(p0, p4); | |
drawProjectedLine(p3, p1); | |
drawProjectedLine(p3, p2); | |
drawProjectedLine(p3, p7); | |
drawProjectedLine(p6, p2); | |
drawProjectedLine(p6, p4); | |
drawProjectedLine(p6, p7); | |
drawProjectedLine(p5, p4); | |
drawProjectedLine(p5, p7); | |
drawProjectedLine(p5, p1); | |
} | |
void setup() { | |
Serial.begin(9600); | |
display.begin(SSD1306_SWITCHCAPVCC); | |
} | |
void loop() { | |
display.clearDisplay(); | |
drawCube(xpos, ypos, zpos, 16); | |
drawCube(32, 32, 32, 12); | |
display.display(); | |
advancePosition(); | |
advanceRotation(); | |
// slow down animation slightly | |
delay(10); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment