#include <FastLED.h>
const uint8_t kMatrixWidth = 32;
const uint8_t kMatrixHeight = 32;
#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
#define LED_PIN 2
#define COLOR_ORDER GRB
#define CHIPSET WS2811
#define BRIGHTNESS 200
CRGB leds[NUM_LEDS + 1];
struct Circle {
int x, y, r;
};
void setup() {
Serial.begin(115200);
FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(UncorrectedColor);
FastLED.setBrightness(BRIGHTNESS);
}
void loop() {
FastLED.clear();
uint32_t ms = millis();
float r = kMatrixHeight / 2 - 1;
float x = kMatrixWidth / 2;
float y = kMatrixHeight / 2;
for (uint8_t count = 5; count--; ) {
if (r >= 1) plotCircleAA({x, y, r}, CRGB(255, 255, 100));
r /= 1.5;
x -= r * sinf(ms / (100.f * count)) / 2.f;
y -= r * cosf(ms / (100.f * count)) / 2.f;
}
FastLED.show();
}
uint16_t xy(uint8_t x, uint8_t y) {
if (x >= kMatrixWidth || y >= kMatrixHeight)
return NUM_LEDS;
uint16_t i = x + (y * kMatrixWidth);
return i;
}
// http://members.chello.at/%7Eeasyfilter/Bresenham.pdf § 7.2
void plotCircleAA(const Circle &circle, const CRGB &color) {
int x = circle.r, y = 0; /* II. quadrant from bottom left to top right */
int i, x2, e2, err = 2 - 2 * circle.r; /* error of 1.step */
int r = 1 - err;
for ( ; ; ) {
i = 255 * abs(err + 2 * (x + y) - 2) / r; /* get blend value of pixel */
CRGB c = color;
fadeToBlackBy(&c, 1, i);
leds[xy(circle.x + x, circle.y - y)] |= c; /* I. Quadrant */
leds[xy(circle.x + y, circle.y + x)] |= c; /* II. Quadrant */
leds[xy(circle.x - x, circle.y + y)] |= c; /* III. Quadrant */
leds[xy(circle.x - y, circle.y - x)] |= c; /* IV. Quadrant */
if (x == 0) break;
e2 = err; x2 = x; /* remember values */
if (err > y) { /* x step */
i = 255 * (err + 2 * x - 1) / r; /* outward pixel */
if (i < 255) {
CRGB c2 = color;
fadeToBlackBy(&c2, 1, i);
leds[xy(circle.x + x, circle.y - y + 1)] |= c2;
leds[xy(circle.x + y - 1, circle.y + x)] |= c2;
leds[xy(circle.x - x, circle.y + y - 1)] |= c2;
leds[xy(circle.x - y + 1, circle.y - x)] |= c2;
}
err -= --x * 2 - 1;
}
if (e2 <= x2--) { /* y step */
i = 255 * (1 - 2 * y - e2) / r; /* inward pixel */
if (i < 255) {
CRGB c2 = color;
fadeToBlackBy(&c2, 1, i);
leds[xy(circle.x + x2, circle.y - y)] |= c2;
leds[xy(circle.x + y, circle.y + x2)] |= c2;
leds[xy(circle.x - x2, circle.y + y)] |= c2;
leds[xy(circle.x - y, circle.y - x2)] |= c2;
}
err -= --y * 2 - 1;
}
}
}