#include <FastLED.h>
#define WIDTH 16
#define HEIGHT 16
#define NUM_LEDS ((WIDTH) * (HEIGHT))
#define POINTS 6
CRGB leds[NUM_LEDS + 1];
uint16_t XY(uint8_t x, uint8_t y) {
if (x >= WIDTH) return NUM_LEDS;
if (y >= HEIGHT) return NUM_LEDS;
if (y & 1)
return (y + 1) * WIDTH - 1 - x;
else
return y * WIDTH + x;
}
#include "wuLineAA.h"
CRGBPalette16 currentPalette = {
0xFF0000, 0x7F0000, 0xAB5500, 0x552A00,
0xABAB00, 0x555500, 0x00FF00, 0x007F00,
0x00AB55, 0x00552A, 0x0000FF, 0x00007F,
0x5500AB, 0x2A0055, 0xAB0055, 0x55002A
};
// x & y are Q7.8 fixed-point
// dx & dy are Q.7 deltas for x & y.
struct Point {
saccum78 x, y;
sfract7 dx, dy;
};
Point points[POINTS];
void setup() {
FastLED.addLeds<NEOPIXEL, 2>(leds, NUM_LEDS);
Serial.begin(115200);
for (uint8_t i = 0; i < POINTS; i++) {
points[i].x = random16() % (WIDTH << 8);
points[i].y = random16() % (HEIGHT << 8);
points[i].dx = (random8() - 128) / 24;
points[i].dy = (random8() - 128) / 24;
}
}
void loop()
{
static int frame; frame++;
uint32_t ms = millis();
FastLED.clear();
// fadeToBlackBy(leds, NUM_LEDS, 25);
// change `effect` every 3-seconds
static uint8_t effect = 0;
EVERY_N_MILLIS(3000) {
// Serial.println(FastLED.getFPS());
if (++effect > 2) effect = 2;
}
// // move the points, and bounce off the edges
// for (uint8_t i = 0; i < POINTS; i++) {
// points[i].x += points[i].dx;
// points[i].y += points[i].dy;
// if (points[i].x <= 0) {
// points[i].dx = -points[i].dx;
// points[i].x = -points[i].x;
// } else if (points[i].x >= WIDTH << 8) {
// points[i].dx = -points[i].dx;
// points[i].x = (WIDTH << 9) - points[i].x;
// }
// if (points[i].y <= 0) {
// points[i].dy = -points[i].dy;
// points[i].y = -points[i].y;
// } else if (points[i].y >= HEIGHT << 8) {
// points[i].dy = -points[i].dy;
// points[i].y = (HEIGHT << 9) - points[i].y;
// }
// }
uint16_t centrex = WIDTH * 128;
uint16_t centrey = HEIGHT * 128;
for (uint8_t i = 0; i < POINTS; i++) {
points[i].x = cos16(ms * 8 + i * (65536 / POINTS)) / (256 / WIDTH + 2) + centrex;
points[i].y = sin16(ms * 8 + i * (65536 / POINTS)) / (256 / HEIGHT + 2) + centrey;
}
// make a colour
// bigger multipliers change the colour faster
// use prime numbers as the multipliers for the longest loop-time
CRGB plot_colour = CRGB(128 + sin16(ms * 13) / 256,
128 + sin16(ms * 17) / 256,
128 + sin16(ms * 29) / 256);
plot_colour = 0xffffff;
// draw lines between each point
for (uint8_t i = 0; i < POINTS; i++) {
switch (effect) {
// show aliased lines
case 0:
plotLine( points[i].x >> 8,
points[i].y >> 8,
points[(i + 1) % POINTS].x >> 8,
points[(i + 1) % POINTS].y >> 8,
&plot_colour);
break;
// ...and anti-aliased
case 1:
plotLineAA( points[i].x >> 8,
points[i].y >> 8,
points[(i + 1) % POINTS].x >> 8,
points[(i + 1) % POINTS].y >> 8,
&plot_colour);
break;
default:
// ...and sub-pixel positioned anti-aliased
wuLineAA( points[i].x,
points[i].y,
points[(i + 1) % POINTS].x,
points[(i + 1) % POINTS].y,
&plot_colour);
}
}
// wuLineAA( 0, 0, (WIDTH << 8) -1, frame % (HEIGHT << 8), &plot_colour);
FastLED.show();
FastLED.delay(50);
}
// from: https://github.com/FastLED/FastLED/pull/202
CRGB ColorFromPaletteExtended(const CRGBPalette16& pal, uint16_t index, uint8_t brightness, TBlendType blendType) {
// Extract the four most significant bits of the index as a palette index.
uint8_t index_4bit = (index >> 12);
// Calculate the 8-bit offset from the palette index.
uint8_t offset = (uint8_t)(index >> 4);
// Get the palette entry from the 4-bit index
const CRGB* entry = &(pal[0]) + index_4bit;
uint8_t red1 = entry->red;
uint8_t green1 = entry->green;
uint8_t blue1 = entry->blue;
uint8_t blend = offset && (blendType != NOBLEND);
if (blend) {
if (index_4bit == 15) {
entry = &(pal[0]);
} else {
entry++;
}
// Calculate the scaling factor and scaled values for the lower palette value.
uint8_t f1 = 255 - offset;
red1 = scale8_LEAVING_R1_DIRTY(red1, f1);
green1 = scale8_LEAVING_R1_DIRTY(green1, f1);
blue1 = scale8_LEAVING_R1_DIRTY(blue1, f1);
// Calculate the scaled values for the neighbouring palette value.
uint8_t red2 = entry->red;
uint8_t green2 = entry->green;
uint8_t blue2 = entry->blue;
red2 = scale8_LEAVING_R1_DIRTY(red2, offset);
green2 = scale8_LEAVING_R1_DIRTY(green2, offset);
blue2 = scale8_LEAVING_R1_DIRTY(blue2, offset);
cleanup_R1();
// These sums can't overflow, so no qadd8 needed.
red1 += red2;
green1 += green2;
blue1 += blue2;
}
if (brightness != 255) {
// nscale8x3_video(red1, green1, blue1, brightness);
nscale8x3(red1, green1, blue1, brightness);
}
return CRGB(red1, green1, blue1);
}