#include <FastLED.h>

#define WIDTH 16
#define HEIGHT 16
#define NUM_LEDS ((WIDTH) * (HEIGHT))
CRGB leds[NUM_LEDS];

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

// map X & Y coordinates onto a horizontal serpentine matrix layout
uint8_t XY(uint8_t x, uint8_t y) {
  if (y & 1)
    return (y + 1) * WIDTH - x - 1;
  return y * WIDTH + x;
}

void loop() {
  const float pi = 3.14159265;
  static uint16_t offset = 0;    // animates the effect
  float distance_factor = 24.f;  // affects density
  for (int8_t y = 0; y < HEIGHT; y++) {
    for (int8_t x = 0; x < WIDTH; x++) {
      // move the origin to the centre of the matrix
      float cx = x - (WIDTH / 2 - 0.5f);
      float cy = y - (HEIGHT / 2 - 0.5f);
      uint16_t distance = hypotf(cy, cx) * (distance_factor / hypotf(WIDTH / 2, HEIGHT / 2));
      leds[XY(x, y)] = ColorFromPalette(OceanColors_p, sin8(distance - offset));
    }
  }
  FastLED.show();
  offset += 1;
}