/// @file Moire.ino
/// @brief Moiré interference patterns 2D effect
/// @example Moire.ino
/// @author sutaburosu
#include <Arduino.h>
#include <FastLED.h>
using namespace fl;
#define HEIGHT 16
#define WIDTH 16
#define NUM_LEDS ((WIDTH) * (HEIGHT))
#define IS_SERPENTINE true
XYMap xyMap(WIDTH, HEIGHT, IS_SERPENTINE);
UITitle title("Moiré");
UIDescription description("Shows a Moiré interference pattern.");
UICheckbox checkboxA("A hypot() or atan2()", true );
UICheckbox checkboxB("B hypot() or atan2()");
UISlider speed("Speed", 3.0f, 0.25f, 20.0f);
UISlider scale("Scale", 1.0f, 0.25f, 10.0f);
UISlider scaleA("Scale A", 3.0f, 1.0f, 16.0f);
UISlider scaleB("Scale B", 3.0f, 1.0f, 16.0f);
CRGB leds[NUM_LEDS];
CRGBPalette16 palette = RainbowColors_p;
void setup()
{
Serial.begin(115200);
FastLED.addLeds<NEOPIXEL, 25>(leds, NUM_LEDS).setScreenMap(xyMap);
}
void loop()
{
struct vec2
{
float x;
float y;
};
// Render a moire pattern
static uint32_t ms = 0;
static float t = 0.0f;
uint32_t newms = millis();
t += (newms - ms) * 0.00005f * float(speed);
ms = newms;
const float m = min(WIDTH, HEIGHT) * float(scale);
const vec2 centreA = {
cosf(t * 3.0f) * 0.5f,
sinf(t * 7.0f) * 0.5f
};
const vec2 centreB = {
cosf(t * 5.0f) * 0.5f,
sinf(t * 4.0f) * 0.5f
};
for (int y = 0; y < HEIGHT; y++)
{
for (int x = 0; x < WIDTH; x++)
{
vec2 coord = {2.0f * (x - WIDTH / 2.0f) / m,
2.0f * (y - HEIGHT / 2.0f) / m
};
float A, B;
if (checkboxA)
A = atan2f(centreA.x - coord.x, centreA.y - coord.y) + t * 1.01f;
else
A = hypotf(centreA.x - coord.x, centreA.y - coord.y);
if (checkboxB)
B = atan2f(centreB.x - coord.x, centreB.y - coord.y) - t * 1.37f;
else
B = hypotf(centreB.x - coord.x, centreB.y - coord.y);
float aMod = 6.282f + (cosf(t * 2.12f) * 0.5f + 0.5f) * float(scaleA);
float bMod = 6.282f + (cosf(t * 3.33f) * 0.5f + 0.5f) * float(scaleB);
float a = cosf(A * aMod);
float b = cosf(B * bMod);
float i = ((a * b) + 1.0f) / 2.0f; // mult
float j = ((a + b) + 2.0f) / 4.0f; // sum
uint16_t valuei16 = uint16_t(i * 65535.0f) + uint16_t(t * 256.f * 300.f);
uint8_t valuej8 = uint8_t(j * 240.0f) + 15;
uint32_t idx = xyMap.mapToIndex(x, y);
leds[idx] = ColorFromPaletteExtended(palette, valuei16, valuej8, LINEARBLEND);
}
}
FastLED.show();
if (1) { // show frame timings
static uint64_t fps_us;
static uint16_t frame;
if (++frame == 100) {
uint64_t time_us = micros() - fps_us;
Serial.print(time_us / float(frame));
Serial.print("us\t");
Serial.print(frame * 1000000.f / time_us, 3);
Serial.println("FPS");
fps_us = micros();
frame = 0;
Serial.println(Fa)
}
}
}Loading
esp32-devkit-c-v4
esp32-devkit-c-v4