#include "FastLED.h"
// Matrix size
#define LED_COLS 40
#define LED_ROWS 40
#define NUM_LEDS LED_COLS * LED_ROWS
#define MATRIX_TYPE 1
// LEDs pin
#define DATA_PIN 3
// LED brightness
#define BRIGHTNESS 255
// Define the array of leds
CRGB leds[NUM_LEDS];

void drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2,
              const CRGB & color) {
  int8_t deltaX = abs(x2 - x1);
  int8_t deltaY = abs(y2 - y1);
  int8_t signX = x1 < x2 ? 1 : -1;
  int8_t signY = y1 < y2 ? 1 : -1;
  int8_t error = deltaX - deltaY;

  leds[XY(x2, y2)] = color;
  while (x1 != x2 || y1 != y2) {
    leds[XY(x1, y1)] = color;
    int8_t error2 = error * 2;
    if (error2 > -deltaY) {
      error -= deltaY;
      x1 += signX;
    }
    if (error2 < deltaX) {
      error += deltaX;
      y1 += signY;
    }
  }
}
#define x1 1
#define y1 1
#define x2 LED_COLS - 2
#define y2 LED_ROWS / 2 - 2
#define x02 LED_COLS - (LED_COLS / 3.3)
#define y02 LED_ROWS / 2 + 1
#define x3 LED_COLS - 2
#define y3 LED_ROWS - 2
void draw() {
  double t = millis() / 60;
  for (uint8_t x = 0; x < LED_COLS; x++) {
    for (uint8_t y = 0; y < LED_ROWS; y++) {
      leds[XY(x, y)].r = (x + t) - y;
      leds[XY(x, y)].g = (x - t) + (y - t);
      leds[XY(x, y)].b = x + (y + t);
    }
  }
  float ax = 0; //sin(radians(t))
  float ay = -1; //cos(radians(t))
  drawLine(x1 + ax, y1 + ay, x02 + ax, y2 + ay, CHSV(0, 0, 0));
  drawLine(x1 + ax, y1 + ay, x2 + ax, y02 + ay, CHSV(0, 0, 0));
  drawLine(x2 + ax, y02 + ay, x1 + (LED_COLS / 3.3) - 1 + ax, y02 + ay, CHSV(0, 0, 0));
  drawLine(x02 + ax, y2 + ay, x1 + ax, y2 + ay, CHSV(0, 0, 0));
  drawLine(x1 + ax, y2 + ay, x3 + ax, y3 + ay, CHSV(0, 0, 0));
  drawLine(x1 + (LED_COLS / 3.3) - 1 + ax, y02 + ay, x3 + ax, y3 + ay, CHSV(0, 0, 0));

  drawLine(x1, y1, x02, y2, CHSV(0, 0, 255));
  drawLine(x1, y1, x2, y02, CHSV(0, 0, 255));
  drawLine(x2, y02, x1 + (LED_COLS / 3.3) - 1, y02, CHSV(0, 0, 255));
  drawLine(x02, y2, x1, y2, CHSV(0, 0, 255));
  drawLine(x1, y2, x3, y3, CHSV(0, 0, 255));
  drawLine(x1 + (LED_COLS / 3.3) - 1, y02, x3, y3, CHSV(0, 0, 255));
  delay(16);
}

void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
}

void loop() {
  draw();
  FastLED.show();
} //loop


uint16_t XY (uint8_t x, uint8_t y) {

  if ((y % 2 == 0) || MATRIX_TYPE)                     // если чётная строка
  {
    return ((uint32_t)(y  + 1) * LED_COLS - 1 - x) % (LED_COLS * LED_ROWS);
  }
  else                                                      // если нечётная строка
  {
    return ((uint32_t)y  * LED_COLS + LED_ROWS - x - 1) % (LED_COLS * LED_ROWS);
  }
}