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

#define TFT_DC 17
#define TFT_CS 16
/*
  SCL   --> 18 (SCK)
  SDA   --> 23 (MOSI)
  RST   --> EN
*/
Adafruit_GC9A01A tft(TFT_CS, TFT_DC);

#define kn   25  //вывод кнопки

// Константы координат смещения центра
const int CENTER_X = 120;
const int CENTER_Y = 120;
bool cvet;//
bool FLAG = false; //
byte UZOR = 1; //
//
int delta_r = 15;//интервалы расброса координат окрестных точек
int delta_F = 70;//

int F1 = 0; //

int N = 8; //число базовых точек
int n = 10; //число окрестных точек
//
long Yp = 0; //
//
int r0 = 0;
float f0 = 0;
int r1 = 0;
float f1 = 0;

//
void setup() {
  pinMode (kn, INPUT_PULLUP);//кнопка
  // Инициализация генератора случайных чисел
  randomSeed(analogRead(32));
  tft.begin();
  tft.fillScreen(GC9A01A_BLACK);
  // tft.cp437(true);
  tft.setRotation(1);
}

void loop() {
  //
  if (millis() - Yp > 60000) {
    Yp = millis();
    UZOR++;
    if (UZOR > 4) {
      UZOR = 1;
    }
  }
  //
  if (UZOR == 1) {
    for (int i = 0; i < random(10, 25); i++) {
      int r1 = random(0, 110); float f1 = (random(0, 101) / 100.0) * (PI / 6.0);
      int r2 = random(0, 110); float f2 = (random(0, 101) / 100.0) * (PI / 6.0);
      int r3 = random(0, 110); float f3 = (random(0, 101) / 100.0) * (PI / 6.0);
      fillTriangleSnowflake(r1, f1, r2 , f2, r3, f3);
      delay_(400);
    }
    tft.fillScreen(GC9A01A_BLACK);
    delay_(400);
  }
  //
  if (UZOR == 2) {
    N = random(5, 12);//псевдослучайный выбор основных параметров снежинки-узора на 1 узор
    n = random(5, 25);
    delta_r = random(5, 20);
    delta_F = random(40, 100);

    //
    for (int j = 0; j < N; j++) {// цикл отстройки базовых точек
      // int r1 = random(0, 110);
      int r1;
      if (j < N / 3) {//условия псевдороста узора от центра
        r1 = random(0, 35);
      }
      if (j >= N / 3 && j < 2 * N / 3) {
        r1 = random(35, 70);
      }
      if (j >= 2 * N / 3 && j < N) {
        r1 = random(70, 110);
      }
      float f1 = (random(0, 101) / 100.0) * (PI / 6.0);
      drawPixelSnowflake(r1, f1);
      //
      for (int i = 0; i < n; i++) { //цикл отстройки окрестных точек
        //
        int r2 = random(r1 - delta_r, r1 + delta_r );
        if (r2 < 0) {
          r2 = 0;
        }
        if (r2 > 100) {
          r2 = 100;
        }
        //
        int F2 = random(F1 - delta_F, F1 + delta_F);
        if (F2 < 0) {
          F2 = 0;
        }
        if (F2 > 100) {
          F2 = 100;
        }

        float f2 = (F2 / 100.0) * (PI / 6.0);
        drawPixelSnowflake(r2, f2);

        delay_(20);
      }
    }
    delay_(1000);
    tft.fillScreen(GC9A01A_BLACK);
    delay_(300);
  }
  //
  if (UZOR == 3) {
    for (int i = 0; i < 10; i++) {
      int r2 = random(0, 110); float f2 = (random(0, 101) / 100.0) * (PI / 6.0);
      drawLineSnowflake(r0, f0, r2 , f2);
      r0 = r2; f0 = f2;
      delay_(300);
    }
    delay_(1000);
    tft.fillScreen(GC9A01A_BLACK);
    delay_(300);
  }
//
if (UZOR == 4){
 delta_r = random(10, 20);
 delta_F = random(10, 20);
 F1 = 0; // 
 for (int i = 0; i < 100; i++) {
    //
    int r2 = random(r1 - delta_r, r1 + delta_r );
    if (r2 < 0) {
      r2 = 0;
    }
    if (r2 > 100) {
      r2 = 100;
    }
    //
    int F2 = random(F1 - delta_F, F1 + delta_F);
    if (F2 < 0) {
      F2 = 0;
    }
    if (F2 > 100) {
      F2 = 100;
    }

    float f2 = (F2 / 100.0) * (PI / 6.0);
    drawLineSnowflake(r1, f1, r2 , f2);
    r1 = r2; f1 = f2; F1 = F2;
    delay_(50);
  }
  delay_(2000);
  tft.fillScreen(GC9A01A_BLACK);
  delay_(300);
}
}
////////////////////////////////////
//функция построения закрашенного треугольника в полярных координатах с центром в центре экрана
void fillTrianglePol(int r1, float f1, int r2, float f2, int r3, float f3) {

  if (cvet) {
    tft.fillTriangle(
      CENTER_X + cos(f1) * r1,
      CENTER_Y + sin(f1) * r1,
      CENTER_X + cos(f2) * r2,
      CENTER_Y + sin(f2) * r2,
      CENTER_X + cos(f3) * r3,
      CENTER_Y + sin(f3) * r3,
      GC9A01A_WHITE
    );
  }
  else {
    tft.fillTriangle(
      CENTER_X + cos(f1) * r1,
      CENTER_Y + sin(f1) * r1,
      CENTER_X + cos(f2) * r2,
      CENTER_Y + sin(f2) * r2,
      CENTER_X + cos(f3) * r3,
      CENTER_Y + sin(f3) * r3,
      GC9A01A_RED
    );
  }

}
//////////////////////////////////
//функция построения 12 отсимметриченных треугольников снежинки по базовому отрезку
void fillTriangleSnowflake (int r1, float f1, int r2, float f2, int r3, float f3) {
  if (r1 > 120 || r2 > 120 || r3 > 120 || r1 < 0 || r2 < 0 || r3 < 0 || f1 < 0.0 || f2 < 0.0 || f3 < 0.0 || f1 > PI / 6.0 || f2 > PI / 6 || f3 > PI / 6) {
    return; //условие рисования базового треугольника в допустимых значениях аргументов (0-120 пикселей радиус, 0-PI/6 угол(сектор))
  }
  cvet = random(0, 2);
  for (float i = 0.01; i < 2 * PI; i += PI / 3.0) {
    fillTrianglePol(r1, f1 + i, r2, f2 + i, r3, f3 + i);
    fillTrianglePol(r1, 2 * PI - f1 + i, r2, 2 * PI - f2 + i, r3, 2 * PI - f3 + i);
  }
}
//////////////////////////////////
//функция построения точки в полярных координатах с центром в центре экрана
void drawPixelPol(int r1, float f1) {
  if (cvet) {
    tft.drawPixel(
      CENTER_X + cos(f1) * r1,
      CENTER_Y + sin(f1) * r1,
      GC9A01A_WHITE
    );
  }
  else {
    tft.drawPixel(
      CENTER_X + cos(f1) * r1,
      CENTER_Y + sin(f1) * r1,
      GC9A01A_RED
    );
  }
}

//////////////////////////////////
//функция построения 12 отсимметриченных точек снежинки по базовой точке
void drawPixelSnowflake (int r1, float f1) {
  if (r1 > 120  || r1 < 0 || f1 < 0.0 || f1 > PI / 6.0 ) {
    return; //условие рисования базового отрезка в допустимых значениях аргументов (0-120 пикселей радиус, 0-PI/6 угол(сектор))
  }
  cvet = random(0, 2);
  for (float i = 0.01; i < 2 * PI; i += PI / 3.0) {
    drawPixelPol(r1, f1 + i);
    drawPixelPol(r1, 2 * PI - f1 + i);
  }
}
//////////////////////////////////
void delay_(int T) {
  long Y = millis(); //
  while (millis() - Y < T) {
    while (digitalRead(kn) == LOW) {
      FLAG = !FLAG;
      delay(200);
      while (FLAG) {
        if (digitalRead(kn) == LOW) {
          break;
        }
        delay(10);
      }
    }
  }

}
//////////////////////////////////
//функция построения отрезка в полярных координатах с центром в центре экрана
void drawLinePol(int r1, float f1, int r2, float f2) {
  if (cvet) {
    tft.drawLine(
      CENTER_X + cos(f1) * r1,
      CENTER_Y + sin(f1) * r1,
      CENTER_X + cos(f2) * r2,
      CENTER_Y + sin(f2) * r2,
      GC9A01A_WHITE
    );
  }
  else {
    tft.drawLine(
      CENTER_X + cos(f1) * r1,
      CENTER_Y + sin(f1) * r1,
      CENTER_X + cos(f2) * r2,
      CENTER_Y + sin(f2) * r2,
      GC9A01A_RED
    );
  }
}
//////////////////////////////////
//функция построения 12 отсимметриченных отрезков снежинки по базовому отрезку
void drawLineSnowflake (int r1, float f1, int r2, float f2) {
  if (r1 > 120 || r2 > 120 || r1 < 0 || r2 < 0 || f1 < 0.0 || f2 < 0.0 || f1 > PI / 6.0 || f2 > PI / 6) {
    return; //условие рисования базового отрезка в допустимых значениях аргументов (0-120 пикселей радиус, 0-PI/6 угол(сектор))
  }
  cvet = random(0, 2);
  for (float i = 0.01; i < 2 * PI; i += PI / 3.0) {
    drawLinePol(r1, f1 + i, r2, f2 + i);
    drawLinePol(r1, 2 * PI - f1 + i, r2, 2 * PI - f2 + i);
  }
}
//////////////////////////////////
