//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/
uno:SCL
uno:SDA
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:14
uno:15
uno:16
uno:17
uno:18
uno:19
uno:20
uno:21
uno:5V.1
uno:5V.2
uno:22
uno:23
uno:24
uno:25
uno:26
uno:27
uno:28
uno:29
uno:30
uno:31
uno:32
uno:33
uno:34
uno:35
uno:36
uno:37
uno:38
uno:39
uno:40
uno:41
uno:42
uno:43
uno:44
uno:45
uno:46
uno:47
uno:48
uno:49
uno:50
uno:51
uno:52
uno:53
uno:GND.4
uno:GND.5
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
uno:A6
uno:A7
uno:A8
uno:A9
uno:A10
uno:A11
uno:A12
uno:A13
uno:A14
uno:A15
neopixels:DOUT
neopixels:VDD
neopixels:VSS
neopixels:DIN