#include <Adafruit_GC9A01A.h>
#include <Adafruit_GFX.h>
#include <SPI.h>
#include <stdlib.h>
#include <math.h>

#define TFT_CS   16  // Chip select pin
#define TFT_DC   17 // Data/command pin
#define TFT_RST  -1 // Reset pin (optional, or connect to 3.3V)

Adafruit_GC9A01A tft = Adafruit_GC9A01A(TFT_CS, TFT_DC, TFT_RST);

struct Point {
  float x, y;
  int R, G, B;
};

const int NUM_POINTS = 40; // Количество точек для диаграммы Вороного

Point points[NUM_POINTS];
/////////////////////////////////////
//функция вычисления метрики (как вариант расстояния между двумя точками)
float dist(float x1, float y1, float x2, float y2, byte m) {
  if (m == 1) {
    return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2)); //Евклидова метрика
  }
  if (m == 2) {
    return (abs(x1 - x2) + abs(y1 - y2)); //Манхэттенская метрика
  }
  if (m == 3) {
    return max(abs(x1 - x2), abs(y1 - y2)); // авторская метрика №1
  }

}
//////////////////////////////////////
void setup() {
  Serial.begin(115200);

  tft.begin();
  tft.fillScreen(GC9A01A_BLACK);

  // Initialize random seed
  randomSeed(analogRead(32));

  // Генерируйте случайные точки со случайными цветами
  for (int i = 0; i < NUM_POINTS; i++) {
    points[i].x = random(tft.width());
    points[i].y = random(tft.height());
    points[i].R = random(256); points[i].G = random(256); points[i].B = random(256);
  }
}

void loop() {
  // Вычислите диаграмму Вороного для каждого пикселя
  for (int x = 0; x < tft.width(); x++) {
    for (int y = 0; y < tft.height(); y++) {
      int closestPoint = 0;
      float minDist = dist(x, y, points[0].x, points[0].y, 3);

      for (int i = 1; i < NUM_POINTS; i++) {
        float d = dist(x, y, points[i].x, points[i].y, 3);
        if (d < minDist) {
          minDist = d;
          closestPoint = i;
        }
      }

      tft.drawPixel(x, y, tft.color565(abs(points[closestPoint].R - 5 * minDist), abs(points[closestPoint].G - 5 * minDist), abs(points[closestPoint].B - 5 * minDist)));

    }
  }
  delay(5000); // Отображение в течение 5 секунд
  //tft.fillScreen(GC9A01A_BLACK);
  // Генерируйте случайные точки со случайными цветами для следующей итерации
  for (int i = 0; i < NUM_POINTS; i++) {
    points[i].x = random(tft.width());
    points[i].y = random(tft.height());
    points[i].R = random(256); points[i].G = random(256); points[i].B = random(256);
  }
}
