//source: https://editor.soulmatelights.com/gallery/2342-radialnuclearnoise

#include "FastLED.h"
#define DATA_PIN 2
#define BRIGHTNESS 255
#define NUM_LEDS 256
#define LED_COLS 16
#define LED_ROWS 16
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
//#define FRAMES_PER_SECOND 60
const uint8_t kMatrixWidth = 16;
const uint8_t kMatrixHeight = 16;

const bool    kMatrixSerpentineLayout = false;

bool setupm = 1;
const uint8_t C_X = LED_COLS / 2;
const uint8_t C_Y = LED_ROWS / 2;
const uint8_t mapp = 255 / LED_COLS;
byte XY_angle[LED_COLS][LED_ROWS];
byte XY_radius[LED_COLS][LED_ROWS];


void setup() {
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS); //setCorrection(TypicalLEDStrip);
  //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
 //Serial.begin(115200);
}

void loop() 
{
  FastLED.clear();
  if (setupm) {
    setupm = 0;
    for (int8_t x = -C_X; x < C_X + (LED_COLS % 2); x++) {
      for (int8_t y = -C_Y; y < C_Y + (LED_ROWS % 2); y++) {
        XY_angle[x + C_X][y + C_Y] = 128 * (atan2(y, x) / PI);
        XY_radius[x + C_X][y + C_Y] = hypot(x, y); //thanks Sutaburosu
      }
    }
  }
  
  static byte speed = 8;
  static uint16_t t;
  t += speed;
  uint16_t t1 = t / 2;
  for (uint8_t x = 0; x < LED_COLS; x++) {
    for (uint8_t y = 0; y < LED_ROWS; y++) {
      byte angle = sin8(t1 / 2 + XY_angle[x][y] * 3);
      byte radius = (XY_radius[x][y] * mapp) * 2 - t;
      byte noise[3] = { inoise8(angle, radius, t1), inoise8(angle, 12032 + t1, radius), inoise8(radius, 120021 + t1, angle) };
      leds[XY(x, y)] = CRGB((noise[0] < 128) ? 0 : (noise[0] - 128) * 3, (noise[1] < 128) ? 0 : (noise[1] - 128) * 3, (noise[2] < 128) ? 0 : (noise[2] - 128) * 3);
    }
  }
  delay(1);
      FastLED.show();

}
 
uint16_t XY( uint8_t x, uint8_t y)
{
  uint16_t i;
  if( kMatrixSerpentineLayout == false) {
    i = (y * kMatrixWidth) + x;
  }
  if( kMatrixSerpentineLayout == true) {
    if( y & 0x01) {
      // Odd rows run backwards
      uint8_t reverseX = (kMatrixWidth - 1) - x;
      i = (y * kMatrixWidth) + reverseX;
    } else {
      // Even rows run forwards
      i = (y * kMatrixWidth) + x;
    }
  }
  return i;
}