fskk1817 发表于 2019-9-22 15:31:31

arduino+ILI9225显示旋转的立方体

论坛原贴https://www.geek-workshop.com/thread-26090-1-1.html是使用OLED12864作为显示,手上只有ILI9225,所以简单修改了一下就可以使用。

#include <memorysaver.h>
#include <UTFT.h>


UTFT myGLCD(ILI9225,A2,A1,A5,A4,A3);

typedef struct Vertex{
int8_t location;
}MyVertex;
typedef struct Edge{
int8_t connection;
}MyEdge;
typedef struct Object{
int numv;
int nume;
MyVertex* v;
MyEdge* e;
float quat;
float offset;
}MyObject;

static MyVertex mp[] ={{ -16, -16,-16}, \
                      {16, -16, -16}, \
                      {16, 16, -16}, \
                      {-16, 16, -16}, \
                      {-16, -16,16}, \
                      {16, -16, 16}, \
                      {16, 16, 16}, \
                      {-16, 16, 16}
};
static MyEdge me[] ={{0, 1}, \
                  {1, 2}, \
                  {2, 3}, \
                  {3, 0}, \
                  {4, 5}, \
                  {5, 6}, \
                  {6, 7}, \
                  {7, 4}, \
                  {0, 4}, \
                  {1, 5}, \
                  {2, 6}, \
                  {3, 7}
};

MyObjectobj={0, 0, mp, me,{1,0,0,0},{0,0,0}};

void setup()   {
Serial.begin(9600);


//correct vertex num and edge num

obj.numv=sizeof(mp)/sizeof(MyVertex);
obj.nume=sizeof(me)/sizeof(MyEdge);
myGLCD.InitLCD();
myGLCD.InitLCD();
myGLCD.clrScr();

delay(1000);

moveObject(obj,0,0,70);
renderObject(obj);

}

static float qdelta={0.999847695f,0,0.0174524f,0};
static float qview={0.25881904510252076234889883762405f,0.9659258262890682867497431997289f,0,0};
static float qtemp;

#define near 1.0
#define far 100.0
#define right 1.8
#define top 1.8

static float proj={
    near/right,    0,         0,                  0, \
    0,         near/top,      0,                  0
//    0,             0,   -(far+near)/(far-near), -2*far*near/(far-near),
//    0,             0,         -1,                   0
};
void loop()
{
rotateObject(obj,qdelta);
//myGLCD.clrScr();   // clears the screen and buffer
//myGLCD.fillScr(VGA_BLACK);

renderObject(obj);
delay(100);
clcObject(obj);
   delay(100);
}


void moveObject(MyObject &mo, float x, float y, float z) {
mo.offset=x;
mo.offset=y;
mo.offset=z;
}

void rotateObject(MyObject &mo, float* q) {
qproduct(q,obj.quat,qtemp);
mo.quat=qtemp;
mo.quat=qtemp;
mo.quat=qtemp;
mo.quat=qtemp;
qnormalized(qtemp);
}

void renderObject(MyObject &mo) {
MyVertex* mv=new MyVertex;

qproduct(qview,mo.quat,qtemp);

for (int i = 0; i < mo.numv; i++) {
    float vtemp;
    iqRot(qtemp,mo.v.location,vtemp);
    vtemp += mo.offset;
    vtemp += mo.offset;
    vtemp += mo.offset;

    MatMulVect(proj, vtemp, mv.location);
}


for (int i = 0; i < mo.nume; i++) {
    int8_t p1 = mo.e.connection;
    int8_t p2 = mo.e.connection;
    myGLCD.setColor(VGA_WHITE);
    myGLCD.drawLine(mv.location+100, mv.location+100, mv.location+100, mv.location+100);
}

delete mv;
}

void clcObject(MyObject &mo) {
MyVertex* mv=new MyVertex;

qproduct(qview,mo.quat,qtemp);

for (int i = 0; i < mo.numv; i++) {
    float vtemp;
    iqRot(qtemp,mo.v.location,vtemp);
    vtemp += mo.offset;
    vtemp += mo.offset;
    vtemp += mo.offset;

    MatMulVect(proj, vtemp, mv.location);
}


for (int i = 0; i < mo.nume; i++) {
    int8_t p1 = mo.e.connection;
    int8_t p2 = mo.e.connection;
    myGLCD.setColor(VGA_BLACK);
    myGLCD.drawLine(mv.location+100, mv.location+100, mv.location+100, mv.location+100);
}

delete mv;
}
float iqRot(float q[],int8_t v[],float result[]){
float prod;
prod =- q * v - q * v - q * v;
prod = q * v + q * v - q * v;
prod = q * v - q * v + q * v;
prod = q * v + q * v - q * v;

result = -prod * q + prod * q - prod * q + prod * q;
result = -prod * q + prod * q + prod * q - prod * q;
result = -prod * q - prod * q + prod * q + prod * q;
}

void qproduct(const float* p, const float* q, float* qr) {
qr = p * q - p * q - p * q - p * q;
qr = p * q + p * q + p * q - p * q;
qr = p * q - p * q + p * q + p * q;
qr = p * q + p * q - p * q + p * q;
}

void qnormalized(float* q) {
float invnorm;
invnorm = fastinvsqrt(q * q + q * q + q * q + q * q);
if (invnorm < 100000000) {
    q *= invnorm;
    q *= invnorm;
    q *= invnorm;
    q *= invnorm;
} else {
    q = 1;
    q = 0;
    q = 0;
    q = 0;
}
}
float fastinvsqrt(float x) {
float halfx = 0.5f * x;
float y = x;
long i = *(long*)&y;
i = 0x5f3759df - (i>>1);
y = *(float*)&i;
y = y * (1.5f - (halfx * y * y));
return y;
}

float MatMulVect(float M[], float V[], int8_t result[]){
for(uint8_t i=0; i<2; i++){
   result = (M*V+M*V+M*V+M)/-V*128;
}
}
页: [1]
查看完整版本: arduino+ILI9225显示旋转的立方体