directory move
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
|
||||
Example sketch for TFT_eSPI library.
|
||||
|
||||
No fonts are needed.
|
||||
|
||||
Draws a 3d rotating cube on the TFT screen.
|
||||
|
||||
Original code was found at http://forum.freetronics.com/viewtopic.php?f=37&t=5495
|
||||
|
||||
*/
|
||||
|
||||
#define BLACK 0x0000
|
||||
#define WHITE 0xFFFF
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
#include <TFT_eSPI.h> // Hardware-specific library
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
|
||||
|
||||
int16_t h;
|
||||
int16_t w;
|
||||
|
||||
int inc = -2;
|
||||
|
||||
float xx, xy, xz;
|
||||
float yx, yy, yz;
|
||||
float zx, zy, zz;
|
||||
|
||||
float fact;
|
||||
|
||||
int Xan, Yan;
|
||||
|
||||
int Xoff;
|
||||
int Yoff;
|
||||
int Zoff;
|
||||
|
||||
struct Point3d
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
};
|
||||
|
||||
struct Point2d
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
int LinestoRender; // lines to render.
|
||||
int OldLinestoRender; // lines to render just in case it changes. this makes sure the old lines all get erased.
|
||||
|
||||
struct Line3d
|
||||
{
|
||||
Point3d p0;
|
||||
Point3d p1;
|
||||
};
|
||||
|
||||
struct Line2d
|
||||
{
|
||||
Point2d p0;
|
||||
Point2d p1;
|
||||
};
|
||||
|
||||
Line3d Lines[20];
|
||||
Line2d Render[20];
|
||||
Line2d ORender[20];
|
||||
|
||||
/***********************************************************************************************************************************/
|
||||
void setup() {
|
||||
|
||||
tft.init();
|
||||
|
||||
h = tft.height();
|
||||
w = tft.width();
|
||||
|
||||
tft.setRotation(1);
|
||||
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
cube();
|
||||
|
||||
fact = 180 / 3.14159259; // conversion from degrees to radians.
|
||||
|
||||
Xoff = 240; // Position the centre of the 3d conversion space into the centre of the TFT screen.
|
||||
Yoff = 160;
|
||||
Zoff = 550; // Z offset in 3D space (smaller = closer and bigger rendering)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************/
|
||||
void loop() {
|
||||
|
||||
// Rotate around x and y axes in 1 degree increments
|
||||
Xan++;
|
||||
Yan++;
|
||||
|
||||
Yan = Yan % 360;
|
||||
Xan = Xan % 360; // prevents overflow.
|
||||
|
||||
SetVars(); //sets up the global vars to do the 3D conversion.
|
||||
|
||||
// Zoom in and out on Z axis within limits
|
||||
// the cube intersects with the screen for values < 160
|
||||
Zoff += inc;
|
||||
if (Zoff > 500) inc = -1; // Switch to zoom in
|
||||
else if (Zoff < 160) inc = 1; // Switch to zoom out
|
||||
|
||||
for (int i = 0; i < LinestoRender ; i++)
|
||||
{
|
||||
ORender[i] = Render[i]; // stores the old line segment so we can delete it later.
|
||||
ProcessLine(&Render[i], Lines[i]); // converts the 3d line segments to 2d.
|
||||
}
|
||||
RenderImage(); // go draw it!
|
||||
|
||||
delay(14); // Delay to reduce loop rate (reduces flicker caused by aliasing with TFT screen refresh rate)
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************/
|
||||
void RenderImage( void)
|
||||
{
|
||||
// renders all the lines after erasing the old ones.
|
||||
// in here is the only code actually interfacing with the OLED. so if you use a different lib, this is where to change it.
|
||||
|
||||
for (int i = 0; i < OldLinestoRender; i++ )
|
||||
{
|
||||
tft.drawLine(ORender[i].p0.x, ORender[i].p0.y, ORender[i].p1.x, ORender[i].p1.y, BLACK); // erase the old lines.
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < LinestoRender; i++ )
|
||||
{
|
||||
uint16_t color = TFT_BLUE;
|
||||
if (i < 4) color = TFT_RED;
|
||||
if (i > 7) color = TFT_GREEN;
|
||||
tft.drawLine(Render[i].p0.x, Render[i].p0.y, Render[i].p1.x, Render[i].p1.y, color);
|
||||
}
|
||||
OldLinestoRender = LinestoRender;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************/
|
||||
// Sets the global vars for the 3d transform. Any points sent through "process" will be transformed using these figures.
|
||||
// only needs to be called if Xan or Yan are changed.
|
||||
void SetVars(void)
|
||||
{
|
||||
float Xan2, Yan2, Zan2;
|
||||
float s1, s2, s3, c1, c2, c3;
|
||||
|
||||
Xan2 = Xan / fact; // convert degrees to radians.
|
||||
Yan2 = Yan / fact;
|
||||
|
||||
// Zan is assumed to be zero
|
||||
|
||||
s1 = sin(Yan2);
|
||||
s2 = sin(Xan2);
|
||||
|
||||
c1 = cos(Yan2);
|
||||
c2 = cos(Xan2);
|
||||
|
||||
xx = c1;
|
||||
xy = 0;
|
||||
xz = -s1;
|
||||
|
||||
yx = (s1 * s2);
|
||||
yy = c2;
|
||||
yz = (c1 * s2);
|
||||
|
||||
zx = (s1 * c2);
|
||||
zy = -s2;
|
||||
zz = (c1 * c2);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************************************************/
|
||||
// processes x1,y1,z1 and returns rx1,ry1 transformed by the variables set in SetVars()
|
||||
// fairly heavy on floating point here.
|
||||
// uses a bunch of global vars. Could be rewritten with a struct but not worth the effort.
|
||||
void ProcessLine(struct Line2d *ret, struct Line3d vec)
|
||||
{
|
||||
float zvt1;
|
||||
int xv1, yv1, zv1;
|
||||
|
||||
float zvt2;
|
||||
int xv2, yv2, zv2;
|
||||
|
||||
int rx1, ry1;
|
||||
int rx2, ry2;
|
||||
|
||||
int x1;
|
||||
int y1;
|
||||
int z1;
|
||||
|
||||
int x2;
|
||||
int y2;
|
||||
int z2;
|
||||
|
||||
int Ok;
|
||||
|
||||
x1 = vec.p0.x;
|
||||
y1 = vec.p0.y;
|
||||
z1 = vec.p0.z;
|
||||
|
||||
x2 = vec.p1.x;
|
||||
y2 = vec.p1.y;
|
||||
z2 = vec.p1.z;
|
||||
|
||||
Ok = 0; // defaults to not OK
|
||||
|
||||
xv1 = (x1 * xx) + (y1 * xy) + (z1 * xz);
|
||||
yv1 = (x1 * yx) + (y1 * yy) + (z1 * yz);
|
||||
zv1 = (x1 * zx) + (y1 * zy) + (z1 * zz);
|
||||
|
||||
zvt1 = zv1 - Zoff;
|
||||
|
||||
if ( zvt1 < -5) {
|
||||
rx1 = 256 * (xv1 / zvt1) + Xoff;
|
||||
ry1 = 256 * (yv1 / zvt1) + Yoff;
|
||||
Ok = 1; // ok we are alright for point 1.
|
||||
}
|
||||
|
||||
xv2 = (x2 * xx) + (y2 * xy) + (z2 * xz);
|
||||
yv2 = (x2 * yx) + (y2 * yy) + (z2 * yz);
|
||||
zv2 = (x2 * zx) + (y2 * zy) + (z2 * zz);
|
||||
|
||||
zvt2 = zv2 - Zoff;
|
||||
|
||||
if ( zvt2 < -5) {
|
||||
rx2 = 256 * (xv2 / zvt2) + Xoff;
|
||||
ry2 = 256 * (yv2 / zvt2) + Yoff;
|
||||
} else
|
||||
{
|
||||
Ok = 0;
|
||||
}
|
||||
|
||||
if (Ok == 1) {
|
||||
|
||||
ret->p0.x = rx1;
|
||||
ret->p0.y = ry1;
|
||||
|
||||
ret->p1.x = rx2;
|
||||
ret->p1.y = ry2;
|
||||
}
|
||||
// The ifs here are checks for out of bounds. needs a bit more code here to "safe" lines that will be way out of whack, so they don't get drawn and cause screen garbage.
|
||||
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************/
|
||||
// line segments to draw a cube. basically p0 to p1. p1 to p2. p2 to p3 so on.
|
||||
void cube(void)
|
||||
{
|
||||
// Front Face.
|
||||
|
||||
Lines[0].p0.x = -50;
|
||||
Lines[0].p0.y = -50;
|
||||
Lines[0].p0.z = 50;
|
||||
Lines[0].p1.x = 50;
|
||||
Lines[0].p1.y = -50;
|
||||
Lines[0].p1.z = 50;
|
||||
|
||||
Lines[1].p0.x = 50;
|
||||
Lines[1].p0.y = -50;
|
||||
Lines[1].p0.z = 50;
|
||||
Lines[1].p1.x = 50;
|
||||
Lines[1].p1.y = 50;
|
||||
Lines[1].p1.z = 50;
|
||||
|
||||
Lines[2].p0.x = 50;
|
||||
Lines[2].p0.y = 50;
|
||||
Lines[2].p0.z = 50;
|
||||
Lines[2].p1.x = -50;
|
||||
Lines[2].p1.y = 50;
|
||||
Lines[2].p1.z = 50;
|
||||
|
||||
Lines[3].p0.x = -50;
|
||||
Lines[3].p0.y = 50;
|
||||
Lines[3].p0.z = 50;
|
||||
Lines[3].p1.x = -50;
|
||||
Lines[3].p1.y = -50;
|
||||
Lines[3].p1.z = 50;
|
||||
|
||||
|
||||
//back face.
|
||||
|
||||
Lines[4].p0.x = -50;
|
||||
Lines[4].p0.y = -50;
|
||||
Lines[4].p0.z = -50;
|
||||
Lines[4].p1.x = 50;
|
||||
Lines[4].p1.y = -50;
|
||||
Lines[4].p1.z = -50;
|
||||
|
||||
Lines[5].p0.x = 50;
|
||||
Lines[5].p0.y = -50;
|
||||
Lines[5].p0.z = -50;
|
||||
Lines[5].p1.x = 50;
|
||||
Lines[5].p1.y = 50;
|
||||
Lines[5].p1.z = -50;
|
||||
|
||||
Lines[6].p0.x = 50;
|
||||
Lines[6].p0.y = 50;
|
||||
Lines[6].p0.z = -50;
|
||||
Lines[6].p1.x = -50;
|
||||
Lines[6].p1.y = 50;
|
||||
Lines[6].p1.z = -50;
|
||||
|
||||
Lines[7].p0.x = -50;
|
||||
Lines[7].p0.y = 50;
|
||||
Lines[7].p0.z = -50;
|
||||
Lines[7].p1.x = -50;
|
||||
Lines[7].p1.y = -50;
|
||||
Lines[7].p1.z = -50;
|
||||
|
||||
|
||||
// now the 4 edge lines.
|
||||
|
||||
Lines[8].p0.x = -50;
|
||||
Lines[8].p0.y = -50;
|
||||
Lines[8].p0.z = 50;
|
||||
Lines[8].p1.x = -50;
|
||||
Lines[8].p1.y = -50;
|
||||
Lines[8].p1.z = -50;
|
||||
|
||||
Lines[9].p0.x = 50;
|
||||
Lines[9].p0.y = -50;
|
||||
Lines[9].p0.z = 50;
|
||||
Lines[9].p1.x = 50;
|
||||
Lines[9].p1.y = -50;
|
||||
Lines[9].p1.z = -50;
|
||||
|
||||
Lines[10].p0.x = -50;
|
||||
Lines[10].p0.y = 50;
|
||||
Lines[10].p0.z = 50;
|
||||
Lines[10].p1.x = -50;
|
||||
Lines[10].p1.y = 50;
|
||||
Lines[10].p1.z = -50;
|
||||
|
||||
Lines[11].p0.x = 50;
|
||||
Lines[11].p0.y = 50;
|
||||
Lines[11].p0.z = 50;
|
||||
Lines[11].p1.x = 50;
|
||||
Lines[11].p1.y = 50;
|
||||
Lines[11].p1.z = -50;
|
||||
|
||||
LinestoRender = 12;
|
||||
OldLinestoRender = LinestoRender;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user