//simle rotozoomer procedure 
//fast led rgb matrix 16x16 demo
//Yaroslaw Turbin, 03.11.2020 
//https://vk.com/ldirko
//https://www.reddit.com/user/ldirko/

//how it's look in emulator: https://wokwi.com/arduino/projects/281176629596652040 
//                           https://editor.soulmatelights.com/gallery/457

#include "FastLED.h"
 
// Matrix size
#define NUM_ROWS 16
#define NUM_COLS 16
#define NUM_LEDS NUM_ROWS * NUM_COLS
 
// LEDs pin
#define DATA_PIN 3
 
// LED brightness
#define BRIGHTNESS 255
 
// Define the array of leds
CRGB leds[NUM_LEDS];
byte ledsbuff[NUM_LEDS];

DEFINE_GRADIENT_PALETTE( temperature_gp ) {
    0,   1, 27,105,
   14,   1, 40,127,
   28,   1, 70,168,
   42,   1, 92,197,
   56,   1,119,221,
   70,   3,130,151,
   84,  23,156,149,
   99,  67,182,112,
  113, 121,201, 52,
  127, 142,203, 11,
  141, 224,223,  1,
  155, 252,187,  2,
  170, 247,147,  1,
  184, 237, 87,  1,
  212, 229, 43,  1,
  226, 220, 15,  1,
  240, 171,  2,  2,
 // 255,  80,  3,  3};
 255,  1,  27,  105};

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

void rotozum (){
CRGBPalette16 myPal = temperature_gp;

static float a =0;

float f= (sin(a/2)+1.1)/1.5;
float kosinus = cos(a)*f;
float sinos= sin(a)*f;

  for (int i = 0; i < NUM_COLS; i++) {
    float u1 =i*kosinus;
    float v1 =i*sinos;
  for (int j = 0; j < NUM_ROWS; j++) {
      byte u = abs8(u1-j*sinos)&(NUM_COLS-1); // NUM_COLS and NUM_ROWS must been 2,4,8,16,32,64 resolution only, use and mask for out of bounds
      byte v = abs8(v1+j*kosinus)&(NUM_ROWS-1);   // NUM_COLS and NUM_ROWS must been 2,4,8,16,32,64 resolution only, use and mask for out of bounds
      leds[XY(i,j)] = ColorFromPalette (myPal, ledsbuff[v*NUM_COLS+u], BRIGHTNESS ); 
      
}                                                              
}
a+=0.1;
}

void plasma (){

uint16_t ms = millis()/3;  

 for (int j = 0; j < NUM_ROWS; j++) {
 int horindexbuff = j*NUM_COLS;
 for (int i = 0; i < NUM_COLS; i++) {
 byte noises =  inoise8 (i * 40, j * 40, ms);	
 ledsbuff[horindexbuff+i] =noises;
   }                                                              
   }
} 

uint16_t XY (uint8_t x, uint8_t y) { return (y * NUM_COLS + x);}		//simple function to find led number in led matrix, 
																	//change this to your routine
																	//or generate XY function for your matrix there:
																	//https://macetech.github.io/FastLED-XY-Map-Generator/