#include <Wire.h>
#include <U8g2lib.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

U8G2_SSD1306_128X64_NONAME_F_HW_I2C display(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 22, /* data=*/ 21);

bool isInsideTriangle(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3);

static uint32_t lastUpdate = 0;

void setup() {
  Wire.begin(21, 22, 400000);
  display.begin();
  display.setFlipMode(1);
}

void loop() {
  // Delay for 1 second
  if (millis() - lastUpdate >= 1000) {
    // Update timer
    lastUpdate = millis();

    // Gera triângulos aleatórios
    for (int i = 0; i < 10; i++) {
      int x1 = random(0, SCREEN_WIDTH);
      int y1 = random(0, SCREEN_HEIGHT);
      int x2 = random(0, SCREEN_WIDTH);
      int y2 = random(0, SCREEN_HEIGHT);
      int x3 = random(0, SCREEN_WIDTH);
      int y3 = random(0, SCREEN_HEIGHT);

      // Desenha o triângulo
      display.drawTriangle(x1, y1, x2, y2, x3, y3);

      // Verifica se um ponto está dentro do triângulo e exibe o resultado
      for (int x = 0; x < SCREEN_WIDTH; x++) {
        for (int y = 0; y < SCREEN_HEIGHT; y++) {
          if (isInsideTriangle(x, y, x1, y1, x2, y2, x3, y3)) {
            display.drawPixel(x, y);
          }
        }
      }

      // Envia o buffer para o display
      display.sendBuffer();

      // Limpa o buffer do display para desenhar o próximo triângulo
      display.clearBuffer();
    }
  }
}

bool isInsideTriangle(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
  float A = 1.0 / 2.0 * (-y2 * x3 + y1 * (-x2 + x3) + x1 * (y2 - y3) + x2 * y3);
  float sign = A < 0.0 ? -1.0 : 1.0;
  float s = (y1 * x3 - x1 * y3 + (y3 - y1) * x + (x1 - x3) * y) * sign;
  float t = (x1 * y2 - y1 * x2 + (y1 - y2) * x + (x2 - x1) * y) * sign;

  return s > 0.0 && t > 0.0 && (s + t) < 2.0 * A * sign;
}