#include <SD.h>
#include <adafruit_1947_Obj.h>
#include <idlers.h>
#include <screen.h>
#include <label.h>

//#include "threeDTest.h"
#include <triDBase.h>
#include <triDVector.h>
#include <arrayList.h>
#include <facetList.h>
#include <stlFile.h>
#include <stlList.h>
#include <triDRender.h>

const float RAD_2_DEG = 180.0 / PI;
const float DEG_2_RAD = PI / 180.0;

float rad_2_deg(float x) {
  return x * RAD_2_DEG;  // Humans like degrees. These two do the traslantions.
}
float deg_2_rad(double x) {
  return (x * DEG_2_RAD);
}

label*      ourLabel;
colorObj    backColor;

triDRotation my_angle;      // This sets the oreantation of the model's drwaing on the screen.
triDPoint    location;   // This sets the location of the model's drawing on the screen.
stlList*     STLModel;   // A model is a list of triangles in 3 space "facets" with normal vectors pointing out.
triDRender*  renderMan;  // triDRender is the engine that reads the model, the prarmeters and makes the 2D drawing.

const byte ANGLE_X_POT_PIN = A0;
const byte ANGLE_Y_POT_PIN = A1;
const byte ANGLE_Z_POT_PIN = A2;

void setupModel(void) {

  STLModel = new stlList("/Test3D.STL");       // Small text model. Like crude boat.
  //STLModel = new stlList("/teensyM.STL");    // Big model, maybe 20 sec. to render?
  //STLModel = new stlList("/hemi.STL");       // Hemisphere. Another big model. About 1 minute to render.
  //renderMan = new triDRender(20,100,180,180);  // Create the render engine with its screen location. (x,y,w,h)
  renderMan = new triDRender(0, 0, 180, 180);  // Create the render engine with its screen location. (x,y,w,h)
  renderMan->begin(STLModel);                  // Slot the model into the render enegine.
  renderMan->setObjScale(5);                   // Set the drawing scale.
  //angle.xRad = deg_2_rad(-150);                // The angle around x axis.
  my_angle.xRad = deg_2_rad(0);                // The angle around x axis.
  my_angle.yRad = deg_2_rad(0);                   // The angle around y axis.
  my_angle.zRad = deg_2_rad(0);                   // The angle around z axis.
  renderMan->setObjAngle(&my_angle);              // Set the orentation.
  location.x = 0;                              // x position offset.
  location.y = 0;                              // y position offset.
  location.z = 30;                             // z position offset.
  renderMan->setObjLoc(&location);             // Set the location offsets in..
  viewList.addObj(renderMan);                  // Add this render object into the screen list. (causing it to draw itself)
}

void setup() {

  Serial.begin(115200);                                          // Fire up serial for debugging.
  Serial.println("We begin..");
  if (!initScreen(ADAFRUIT_1947, ADA_1947_SHIELD_CS, PORTRAIT)) { // Init screen.
    Serial.println("NO SCREEN!");                               // Screen init failed. Tell user.
    Serial.flush();                                             // Make sure the message gets out.
    while (true);                                               // Lock the process here.
  }
  if (!SD.begin(ADA_1947_SHIELD_SDCS)) {                         // With icons, we now MUST have an SD card.
    Serial.println("NO SD CARD!");                              // Tell user we have no SD card.
    Serial.flush();                                             // Make sure the message gets out.
    while (true);                                               // Lock the process here.
  }
  backColor.setColor(LC_LIGHT_BLUE);
  screen->fillScreen(&backColor);                                    // Lets set the screen to the back color.

  ourLabel = new label(40, 40, 100, 18, "Test");                 // Create a label object.
  ourLabel->setTextSize(2);                                      // Set the second Adafruit text size.
  ourLabel->setColors(&red, &backColor);                         // We'll draw in red with backColor as background.
  viewList.addObj(ourLabel);                                     // Add the label to the mamanger list.
  ourLabel->setNeedRefresh();
  setupModel();                                                  // This fires up the 3D rendering stuff. BUT seeing
  Serial.println("The end of the beginning.");
}

const float RAW_2_DEG = 360.0 / 1024.0 - 180.0;
const float RAW_2_RAD = 2 * PI / 1024.0 - PI;

void PrintAngle(const char xyz, const uint16_t raw, const float deg, const float rad)
{
  Serial.print(xyz);
  Serial.print(": ");
  Serial.print(raw);
  Serial.print("\t");
  Serial.print(deg);
  Serial.print("\t");
  Serial.print(rad);
  Serial.print("\t\t");
}

void rotateCartesian(twoDPoint *point, const double angle_rad, const twoDPoint *center)
{
  const double cos_alpha = cos(angle_rad);
  const double sin_alpha = sin(angle_rad);

  // Subtract the offset if available.
  if (center != nullptr)
  {
    point->x -= center->x;
    point->y -= center->y;
  }

  // Cartesian rotation.
  twoDPoint new_point =
  {
    point->x * cos_alpha - point->y * sin_alpha,
    point->y * cos_alpha + point->x * sin_alpha
  };

  // Add the offset if available.
  if (center != nullptr)
  {
    point->x = new_point.x + center->x;
    point->y = new_point.y + center->y;
  }
  else
  {
    point->x = new_point.x;
    point->y = new_point.y;
  }
}

void rotatePolar(twoDPoint *point, const double angle_rad, const twoDPoint *center)
{
  double magnitude;
  double theta_rad;

  // Subtract the offset if available.
  if (center != nullptr)
  {
    point->x -= center->x;
    point->y -= center->y;
  }

  // Convert from Cartesian to Polar form.
  magnitude = hypot(point->x, point->y);
  theta_rad = atan2(point->y, point->x);

  // Add the angle
  theta_rad += angle_rad;

  // Convert back to Cartesian form.
  point->x = magnitude * cos(theta_rad);
  point->y = magnitude * sin(theta_rad);

  // Add the offset if available.
  if (center != nullptr)
  {
    point->x += center->x;
    point->y += center->y;
  }
}

void loop()
{
  uint16_t x_raw = analogRead(ANGLE_X_POT_PIN);
  uint16_t y_raw = analogRead(ANGLE_Y_POT_PIN);
  uint16_t z_raw = analogRead(ANGLE_Z_POT_PIN);
  float x_deg = x_raw * RAW_2_DEG;
  float y_deg = y_raw * RAW_2_DEG;
  float z_deg = z_raw * RAW_2_DEG;
  my_angle.xRad = x_raw * RAW_2_RAD;
  my_angle.yRad = y_raw * RAW_2_RAD;
  my_angle.zRad = z_raw * RAW_2_RAD;
  float cos_x = cos(my_angle.xRad);
  Serial.println();
//   PrintAngle('x', x_raw, x_deg, my_angle.xRad);
//   PrintAngle('y', y_raw, y_deg, my_angle.yRad);
//   PrintAngle('z', z_raw, z_deg, my_angle.zRad);
  twoDPoint point1 = { 50, 100 };
  twoDPoint point2 = { 50, 100 };
  twoDPoint center = { x_raw, y_raw };
  rotatePolar(&point1, my_angle.zRad, &center);
  rotateCartesian(&point2, my_angle.zRad, &center);
  Serial.print("point1 = ");
  Serial.print(point1.x);
  Serial.print(", ");
  Serial.print(point1.y);
  Serial.print("\t\tpoint2 = ");
  Serial.print(point2.x);
  Serial.print(", ");
  Serial.print(point2.y);

  renderMan->setObjAngle(&my_angle);  // Has no effect. How do we update on the fly?
  idle();
}
Loading
ili9341-cap-touch