//Stepko
#include "FastLED.h"

// Matrix size
#define LED_COLS 16
#define LED_ROWS 16
#define NUM_LEDS LED_ROWS * LED_COLS
// LEDs pin
#define DATA_PIN 3
// LED brightness
#define BRIGHTNESS 255
// Define the array of leds
CRGB leds[NUM_LEDS + 1];

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

#define C_HEIGHT round((float)LED_COLS / sqrt(2))
#define C_WIDTH round((float)LED_COLS * sqrt(2) * PI)
#define a 360 / (C_WIDTH+1)
bool setupm = 1;
#define C_X (LED_COLS / 2)
#define C_Y (LED_ROWS / 2)
void loop() {
  static int C_XY[C_WIDTH][C_HEIGHT];
  if (setupm) {
    setupm = 0;
    for (int16_t al = 0; al < 10000; al += 10) {
      FastLED.clear();
      for (int16_t x = C_WIDTH - 1; x >= 0; x--) {
        float angle = radians(((x - 1) * a) + (float)al / 100);
        for (byte y = 0; y < C_HEIGHT; y++) {
          int8_t m_x = C_X + (sin(angle) * (y + 1));
          int8_t m_y = C_Y + (cos(angle) * (y + 1));
          //Serial.println(String(m_x)+','+String(m_y));
          C_XY[x][y] = (((m_x < 0 ) || (m_x > LED_COLS - 1)) || ((m_y < 0 ) || (m_y > LED_ROWS - 1))) ? LED_COLS * LED_ROWS : XY(m_x, m_y);
        }
      } 
      for (byte x = 0; x < C_WIDTH; x++) {
        for (byte y = 0; y < C_HEIGHT; y++) {
          leds[C_XY[x][y]] += CHSV(150, 255, 100);
        }
        //FastLED.show();
      }
      bool isBlack = 0;
      for (byte y = 0; y < LED_ROWS; y++) {
        for (byte x = 0; x < LED_COLS; x++) {
          if (!leds[XY(x, y)]) {
            isBlack = 1;
            break;
          }
        }
      } //FastLED.show();
      //Serial.println(String(al) + ',' + String(isBlack));
      if (!isBlack) break;
    }
  }
  static uint16_t hue, r;
  hue++; if(r >= C_WIDTH-1)r=0; else r++;
  for (byte y = 0; y < C_HEIGHT; y++) {
    leds[C_XY[r][y]]=CHSV(y + hue, 255, 255);
  }
  FastLED.show();
}


uint16_t XY (uint8_t x, uint8_t y) {
  return (y * LED_COLS + x);
}