Skip to content

Instantly share code, notes, and snippets.

@smcl
Created January 3, 2016 20:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smcl/cbf796562bf74bba3d78 to your computer and use it in GitHub Desktop.
Save smcl/cbf796562bf74bba3d78 to your computer and use it in GitHub Desktop.
a couple of rotating cubes - using the SSD1306 module from Adafruit
#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