/* Focus on diagram (e.g. by clicking on the matrix)
w p
a s o
d i
*/
#include "FastLED.h"
// Matrix size
#define HEIGHT 20
#define WIDTH 20
// Define pins
#define DATA_PIN 3
#define BUTTON_0 9
#define BUTTON_1 10
#define BUTTON_2 11
#define BUTTON_3 12
#define BUTTON_4 5
#define BUTTON_5 6
#define BUTTON_6 7
// LED brightness
#define BRIGHTNESS 255
// Define the array of leds
#define NUM_LEDS 257
CRGB leds[257];
byte pressed = 0;
bool button0Pressed = false;
bool button1Pressed = false;
bool button2Pressed = false;
bool button3Pressed = false;
bool button4Pressed = false;
bool button5Pressed = false;
bool button6Pressed = false;
void setup() {
pinMode(BUTTON_0, INPUT_PULLUP);
pinMode(BUTTON_1, INPUT_PULLUP);
pinMode(BUTTON_2, INPUT_PULLUP);
pinMode(BUTTON_3, INPUT_PULLUP);
pinMode(BUTTON_4, INPUT_PULLUP);
pinMode(BUTTON_5, INPUT_PULLUP);
pinMode(BUTTON_6, INPUT_PULLUP);
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
}
void loop() {
// Read the button inputs
button0Pressed = digitalRead(BUTTON_0) == LOW;
button1Pressed = digitalRead(BUTTON_1) == LOW;
button2Pressed = digitalRead(BUTTON_2) == LOW;
button3Pressed = digitalRead(BUTTON_3) == LOW;
button4Pressed = digitalRead(BUTTON_4) == LOW;
button5Pressed = digitalRead(BUTTON_5) == LOW;
button6Pressed = digitalRead(BUTTON_6) == LOW;
if (button0Pressed) {
pressed = 1;
} else if (button1Pressed) {
pressed = 2;
} else if (button2Pressed) {
pressed = 3;
} else if (button3Pressed) {
pressed = 4;
} else if (button4Pressed) {
pressed = 5;
} else if (button5Pressed) {
pressed = 6;
} else if (button6Pressed) {
pressed = 7;
}
else pressed = 0;
draw();
FastLED.show();
delay(16);
}
#define MAP_W WIDTH
#define MAP_H HEIGHT
#define RAY_LENGHT_M MAP_W + MAP_H
#define MAP_W WIDTH
#define MAP_H HEIGHT
#define RAY_LENGHT_M MAP_W + MAP_H
int lightersPosY = 10;
int lightersPosX = 10;
byte PosX;
byte PosY;
byte lightersSpeed = 4;
int alpha = 0;
float angle;
byte rot = 10;
bool ThreeD = false;
bool mape[MAP_W][MAP_H];
byte POV = WIDTH;
byte PoV = POV / 2;
bool loadingFlag = true;
void draw() {
if (loadingFlag) {
loadingFlag = false;
}
FastLED.clear();
if (pressed == 1) {
lightersPosX += sin(angle) * lightersSpeed;
lightersPosY += cos(angle) * lightersSpeed;
if (lightersPosX < 0) lightersPosX = (MAP_W - 1) * 4;
if (lightersPosX > (MAP_W - 1) * 4) lightersPosX = 0;
if (lightersPosY < 0) lightersPosY = (MAP_H - 1) * 4;
if (lightersPosY > (MAP_H - 1) * 4) lightersPosY = 0;
PosX = lightersPosX / 4;
PosY = lightersPosY / 4;
}
else if (pressed == 2) {
float angle = radians(alpha);
lightersPosX -= sin(angle) * lightersSpeed;
lightersPosY -= cos(angle) * lightersSpeed;
if (lightersPosX < 0) lightersPosX = (MAP_W - 1) * 4;
if (lightersPosX > (MAP_W - 1) * 4) lightersPosX = 0;
if (lightersPosY < 0) lightersPosY = (MAP_H - 1) * 4;
if (lightersPosY > (MAP_H - 1) * 4) lightersPosY = 0;
PosX = lightersPosX / 4;
PosY = lightersPosY / 4;
}
if (pressed == 3) {
alpha += rot;
angle = radians(alpha);
}
else if (pressed == 4) {
alpha -= rot;
angle = radians(alpha);
}
if (pressed == 5) {
POV ++;
if (POV >= 255) POV = 254; PoV = POV / 2;
}
else if (pressed == 6) {
POV --;
if (POV <= 0) POV = 1;
PoV = POV / 2;
}
if (pressed == 7) {
ThreeD = !ThreeD;
delay(100);
}
for (byte pov = 0; pov < POV+1; pov++) {
byte dist = 0;
byte hdist = 0;
float angleR = radians(alpha + pov - PoV - 1);
float angle_a = sin(angleR);
float angle_b = cos(angleR);
for (byte i = 0; i < (RAY_LENGHT_M); i++) {
if (mape[byte(PosX + (i * angle_a))][byte(PosY + (i * angle_b))] || PosX + (i * angle_a) < 0 || PosX + (i * angle_a) >= MAP_W || PosY + (i * angle_b) < 0 || PosY + (i * angle_b) >= MAP_H) {
if (ThreeD) {
dist = map(i, 0, RAY_LENGHT_M, 255, 0);
hdist = map(i, 0, RAY_LENGHT_M, HEIGHT / 2, 1);
} else {
leds[XY(PosX + ((i - 1) * angle_a), PosY + ((i - 1) * angle_b))] += CHSV(0, 0, 100);
} break;
}
else if (!ThreeD) {
leds[XY(PosX + (i * angle_a), PosY + (i * angle_b))] += CHSV(50, 200, 100);
}
}
if (ThreeD) {
for (byte y = 0; y < HEIGHT / 2 - hdist; y++) {
leds[XY(map(pov, 0, POV, 0, WIDTH - 1), y)] = CHSV(50, 100, ~(y * (256 / HEIGHT * 2)));
} for (byte y = HEIGHT / 2 - hdist; y < HEIGHT / 2 + hdist; y++) {
leds[XY(map(pov, 0, POV, 0, WIDTH - 1), y)] = CHSV(50, 200, dist);
}
}
}
}
uint16_t XY(byte x, byte y) {
static const uint16_t FibonPlanarTable[] PROGMEM ={
256,256,256,256,256,256,256,256,36,39,38,37,256,256,256,256,256,256,256,256,256,256,256,256,256,13,34,35,40,
256,58,59,60,61,256,256,256,256,256,256,256,256,256,256,14,33,256,41,56,57,68,67,66,65,64,63,256,256,256,256,
256,256,256,12,15,32,42,55,256,69,256,79,80,81,82,83,62,256,256,256,256,256,11,16,31,256,43,54,70,77,78,94,
93,92,91,90,84,85,256,256,256,255,10,17,30,44,53,71,76,256,95,256,101,102,103,104,89,88,256,256,256,254,9,18,
29,45,52,72,75,96,256,100,120,119,118,117,105,106,87,256,256,253,8,19,28,46,256,51,73,97,99,121,124,125,126,
256,116,256,107,86,232,252,7,20,256,27,47,256,50,74,122,123,145,144,256,127,256,115,256,108,233,251,6,256,21,
256,26,48,49,256,98,146,147,148,143,256,128,256,114,109,231,234,250,5,256,22,23,25,24,0,195,171,170,169,149,
142,256,129,113,110,230,235,256,249,4,3,2,1,244,243,256,194,172,256,168,150,141,130,112,256,256,229,236,256,
248,247,246,245,242,220,219,196,193,173,167,151,140,131,111,256,256,208,228,237,238,239,240,241,256,221,218,
197,192,174,166,152,139,132,256,256,256,256,209,227,226,256,256,256,222,256,217,198,191,175,165,153,138,133,
256,256,256,256,207,210,211,225,224,223,215,216,199,256,190,176,164,154,137,134,256,256,256,256,256,206,205,
212,213,214,201,200,256,189,177,163,256,155,136,256,256,256,256,256,256,256,256,204,203,202,256,187,188,178,
162,256,156,135,256,256,256,256,256,256,256,256,256,183,184,185,186,180,179,161,256,157,256,256,256,256,256,
256,256,256,256,256,256,256,256,182,181,159,160,256,158,256,256,256,256,256,256,256
};
uint16_t ledsindex = pgm_read_word (FibonPlanarTable+y*WIDTH+x);
return (ledsindex);
}