Added new demo

Based on Aurora code.
This commit is contained in:
mrfaptastic 2019-05-11 15:20:53 +01:00
parent 95dd8aa339
commit 85d0d44891
39 changed files with 5126 additions and 1 deletions

View file

@ -196,6 +196,8 @@ void RGB64x32MatrixPanel_I2S_DMA::updateMatrixDMABuffer(int16_t x_coord, int16_t
// Need to check that the co-ordinates are within range, or it'll break everything big time.
if ( x_coord < 0 || y_coord < 0 || x_coord >= MATRIX_WIDTH || y_coord >= MATRIX_HEIGHT)
{
// Serial.printf("Invalid: x %d, y %d - r %d, g %d, b %d\n", (int)x_coord, (int)y_coord, (int)red, (int)green, (int)blue );
// x_coord = y_coord = 1;
return;
}

View file

@ -0,0 +1,50 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from "Attractor" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/
* Copyright (c) 2014 Daniel Shiffman
* http://www.shiffman.net
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "Vector.h"
class Attractor {
public:
float mass; // Mass, tied to size
float G; // Gravitational Constant
PVector location; // Location
Attractor() {
location = PVector(MATRIX_CENTRE_X, MATRIX_CENTRE_Y);
mass = 10;
G = .5;
}
PVector attract(Boid m) {
PVector force = location - m.location; // Calculate direction of force
float d = force.mag(); // Distance between objects
d = constrain(d, 5.0, 32.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction)
float strength = (G * mass * m.mass) / (d * d); // Calculate gravitional force magnitude
force *= strength; // Get force vector --> magnitude * direction
return force;
}
};

View file

@ -0,0 +1,101 @@
/* ------------------------- CUSTOM GPIO PIN MAPPING ------------------------- */
#define R1_PIN 18
#define G1_PIN 25
#define B1_PIN 5
#define R2_PIN 17
#define G2_PIN 26
#define B2_PIN 16
#define A_PIN 14
#define B_PIN 27
#define C_PIN 12
#define D_PIN 4
#define E_PIN -1
#define LAT_PIN 13
#define OE_PIN 15
#define CLK_PIN 2
/* -------------------------- Display Config Initialisation -------------------- */
#define MATRIX_WIDTH 64
#define MATRIX_HEIGHT 32
/* -------------------------- Class Initialisation -------------------------- */
#include <ESP32-RGB64x32MatrixPanel-I2S-DMA.h>
RGB64x32MatrixPanel_I2S_DMA matrix;
#include <FastLED.h>
#include "Effects.h"
Effects effects;
#include "Drawable.h"
#include "Playlist.h"
//#include "Geometry.h"
#include "Patterns.h"
Patterns patterns;
/* -------------------------- Some variables -------------------------- */
unsigned long ms_current = 0;
unsigned long ms_previous = 0;
unsigned long ms_animation_max_duration = 10000; // 10 seconds
unsigned long next_frame = 0;
void setup()
{
// Setup serial interface
Serial.begin(115200);
delay(250);
matrix.begin(R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, LAT_PIN, OE_PIN, CLK_PIN ); // setup the LED matrix
Serial.println("**************** Starting Aurora Effects Demo ****************");
// setup the effects generator
effects.Setup();
delay(500);
Serial.println("Effects being loaded: ");
listPatterns();
patterns.setPattern(0); // // simple noise
patterns.start();
Serial.print("Starting with pattern: ");
Serial.println(patterns.getCurrentPatternName());
}
void loop()
{
// menu.run(mainMenuItems, mainMenuItemCount);
ms_current = millis();
if ( (ms_current - ms_previous) > ms_animation_max_duration )
{
// patterns.moveRandom(1);
patterns.stop();
patterns.move(1);
patterns.start();
Serial.print("Changing pattern to: ");
Serial.println(patterns.getCurrentPatternName());
ms_previous = ms_current;
// Select a random palette as well
//effects.RandomPalette();
}
if ( next_frame < ms_current)
next_frame = patterns.drawFrame() + ms_current;
}
void listPatterns() {
patterns.listPatterns();
}

326
examples/AuroraDemo/Boid.h Normal file
View file

@ -0,0 +1,326 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from "Flocking" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/
* Copyright (c) 2014 Daniel Shiffman
* http://www.shiffman.net
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// Flocking
// Daniel Shiffman <http://www.shiffman.net>
// The Nature of Code, Spring 2009
// Boid class
// Methods for Separation, Cohesion, Alignment added
class Boid {
public:
PVector location;
PVector velocity;
PVector acceleration;
float maxforce; // Maximum steering force
float maxspeed; // Maximum speed
float desiredseparation = 4;
float neighbordist = 8;
byte colorIndex = 0;
float mass;
boolean enabled = true;
Boid() {}
Boid(float x, float y) {
acceleration = PVector(0, 0);
velocity = PVector(randomf(), randomf());
location = PVector(x, y);
maxspeed = 1.5;
maxforce = 0.05;
}
static float randomf() {
return mapfloat(random(0, 255), 0, 255, -.5, .5);
}
static float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void run(Boid boids [], uint8_t boidCount) {
flock(boids, boidCount);
update();
// wrapAroundBorders();
// render();
}
// Method to update location
void update() {
// Update velocity
velocity += acceleration;
// Limit speed
velocity.limit(maxspeed);
location += velocity;
// Reset acceleration to 0 each cycle
acceleration *= 0;
}
void applyForce(PVector force) {
// We could add mass here if we want A = F / M
acceleration += force;
}
void repelForce(PVector obstacle, float radius) {
//Force that drives boid away from obstacle.
PVector futPos = location + velocity; //Calculate future position for more effective behavior.
PVector dist = obstacle - futPos;
float d = dist.mag();
if (d <= radius) {
PVector repelVec = location - obstacle;
repelVec.normalize();
if (d != 0) { //Don't divide by zero.
// float scale = 1.0 / d; //The closer to the obstacle, the stronger the force.
repelVec.normalize();
repelVec *= (maxforce * 7);
if (repelVec.mag() < 0) { //Don't let the boids turn around to avoid the obstacle.
repelVec.y = 0;
}
}
applyForce(repelVec);
}
}
// We accumulate a new acceleration each time based on three rules
void flock(Boid boids [], uint8_t boidCount) {
PVector sep = separate(boids, boidCount); // Separation
PVector ali = align(boids, boidCount); // Alignment
PVector coh = cohesion(boids, boidCount); // Cohesion
// Arbitrarily weight these forces
sep *= 1.5;
ali *= 1.0;
coh *= 1.0;
// Add the force vectors to acceleration
applyForce(sep);
applyForce(ali);
applyForce(coh);
}
// Separation
// Method checks for nearby boids and steers away
PVector separate(Boid boids [], uint8_t boidCount) {
PVector steer = PVector(0, 0);
int count = 0;
// For every boid in the system, check if it's too close
for (int i = 0; i < boidCount; i++) {
Boid other = boids[i];
if (!other.enabled)
continue;
float d = location.dist(other.location);
// If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
if ((d > 0) && (d < desiredseparation)) {
// Calculate vector pointing away from neighbor
PVector diff = location - other.location;
diff.normalize();
diff /= d; // Weight by distance
steer += diff;
count++; // Keep track of how many
}
}
// Average -- divide by how many
if (count > 0) {
steer /= (float) count;
}
// As long as the vector is greater than 0
if (steer.mag() > 0) {
// Implement Reynolds: Steering = Desired - Velocity
steer.normalize();
steer *= maxspeed;
steer -= velocity;
steer.limit(maxforce);
}
return steer;
}
// Alignment
// For every nearby boid in the system, calculate the average velocity
PVector align(Boid boids [], uint8_t boidCount) {
PVector sum = PVector(0, 0);
int count = 0;
for (int i = 0; i < boidCount; i++) {
Boid other = boids[i];
if (!other.enabled)
continue;
float d = location.dist(other.location);
if ((d > 0) && (d < neighbordist)) {
sum += other.velocity;
count++;
}
}
if (count > 0) {
sum /= (float) count;
sum.normalize();
sum *= maxspeed;
PVector steer = sum - velocity;
steer.limit(maxforce);
return steer;
}
else {
return PVector(0, 0);
}
}
// Cohesion
// For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location
PVector cohesion(Boid boids [], uint8_t boidCount) {
PVector sum = PVector(0, 0); // Start with empty vector to accumulate all locations
int count = 0;
for (int i = 0; i < boidCount; i++) {
Boid other = boids[i];
if (!other.enabled)
continue;
float d = location.dist(other.location);
if ((d > 0) && (d < neighbordist)) {
sum += other.location; // Add location
count++;
}
}
if (count > 0) {
sum /= count;
return seek(sum); // Steer towards the location
}
else {
return PVector(0, 0);
}
}
// A method that calculates and applies a steering force towards a target
// STEER = DESIRED MINUS VELOCITY
PVector seek(PVector target) {
PVector desired = target - location; // A vector pointing from the location to the target
// Normalize desired and scale to maximum speed
desired.normalize();
desired *= maxspeed;
// Steering = Desired minus Velocity
PVector steer = desired - velocity;
steer.limit(maxforce); // Limit to maximum steering force
return steer;
}
// A method that calculates a steering force towards a target
// STEER = DESIRED MINUS VELOCITY
void arrive(PVector target) {
PVector desired = target - location; // A vector pointing from the location to the target
float d = desired.mag();
// Normalize desired and scale with arbitrary damping within 100 pixels
desired.normalize();
if (d < 4) {
float m = map(d, 0, 100, 0, maxspeed);
desired *= m;
}
else {
desired *= maxspeed;
}
// Steering = Desired minus Velocity
PVector steer = desired - velocity;
steer.limit(maxforce); // Limit to maximum steering force
applyForce(steer);
//Serial.println(d);
}
void wrapAroundBorders() {
if (location.x < 0) location.x = MATRIX_WIDTH - 1;
if (location.y < 0) location.y = MATRIX_HEIGHT - 1;
if (location.x >= MATRIX_WIDTH) location.x = 0;
if (location.y >= MATRIX_HEIGHT) location.y = 0;
}
void avoidBorders() {
PVector desired = velocity;
if (location.x < 8) desired = PVector(maxspeed, velocity.y);
if (location.x >= MATRIX_WIDTH - 8) desired = PVector(-maxspeed, velocity.y);
if (location.y < 8) desired = PVector(velocity.x, maxspeed);
if (location.y >= MATRIX_HEIGHT - 8) desired = PVector(velocity.x, -maxspeed);
if (desired != velocity) {
PVector steer = desired - velocity;
steer.limit(maxforce);
applyForce(steer);
}
if (location.x < 0) location.x = 0;
if (location.y < 0) location.y = 0;
if (location.x >= MATRIX_WIDTH) location.x = MATRIX_WIDTH - 1;
if (location.y >= MATRIX_HEIGHT) location.y = MATRIX_HEIGHT - 1;
}
bool bounceOffBorders(float bounce) {
bool bounced = false;
if (location.x >= MATRIX_WIDTH) {
location.x = MATRIX_WIDTH - 1;
velocity.x *= -bounce;
bounced = true;
}
else if (location.x < 0) {
location.x = 0;
velocity.x *= -bounce;
bounced = true;
}
if (location.y >= MATRIX_HEIGHT) {
location.y = MATRIX_HEIGHT - 1;
velocity.y *= -bounce;
bounced = true;
}
else if (location.y < 0) {
location.y = 0;
velocity.y *= -bounce;
bounced = true;
}
return bounced;
}
void render() {
//// Draw a triangle rotated in the direction of velocity
//float theta = velocity.heading2D() + radians(90);
//fill(175);
//stroke(0);
//pushMatrix();
//translate(location.x,location.y);
//rotate(theta);
//beginShape(TRIANGLES);
//vertex(0, -r*2);
//vertex(-r, r*2);
//vertex(r, r*2);
//endShape();
//popMatrix();
//matrix.drawBackgroundPixelRGB888(location.x, location.y, CRGB::Blue);
}
};
static const uint8_t AVAILABLE_BOID_COUNT = 40;
Boid boids[AVAILABLE_BOID_COUNT];

View file

@ -0,0 +1,55 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef Drawable_H
#define Drawable_H
class Drawable{
public:
char* name;
virtual bool isRunnable() {
return false;
}
virtual bool isPlaylist() {
return false;
}
// a single frame should be drawn as fast as possible, without any delay or blocking
// return how many millisecond delay is requested before the next call to drawFrame()
virtual unsigned int drawFrame() {
matrix.fillScreen(0);
//backgroundLayer.fillScreen({ 0, 0, 0 });
return 0;
};
virtual void printTesting()
{
Serial.println("Testing...");
}
virtual void start() {};
virtual void stop() {};
};
#endif

View file

@ -0,0 +1,823 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from "Funky Clouds" by Stefan Petrick: https://gist.github.com/anonymous/876f908333cd95315c35
* Portions of this code are adapted from "NoiseSmearing" by Stefan Petrick: https://gist.github.com/StefanPetrick/9ee2f677dbff64e3ba7a
* Copyright (c) 2014 Stefan Petrick
* http://www.stefan-petrick.de/wordpress_beta
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef Effects_H
#define Effects_H
/* ---------------------------- GLOBAL CONSTANTS ----------------------------- */
const int MATRIX_CENTER_X = MATRIX_WIDTH / 2;
const int MATRIX_CENTER_Y = MATRIX_HEIGHT / 2;
const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1;
const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1;
const uint16_t NUM_LEDS = (MATRIX_WIDTH * MATRIX_HEIGHT) + 1; // one led spare to capture out of bounds
/* Convert x,y co-ordinate to flat array index.
* x and y positions start from 0, so must not be >= 'real' panel width or height
* (i.e. 64 pixels or 32 pixels.). Max value: MATRIX_WIDTH-1 etc.
*/
uint16_t XY( uint8_t x, uint8_t y)
{
if( x >= MATRIX_WIDTH || x < 0) return 0;
if( y >= MATRIX_HEIGHT || y < 0) return 0;
return (y * MATRIX_WIDTH) + x + 1; // everything offset by one to capute out of bounds stuff - never displayed by ShowFrame()
}
uint8_t beatcos8(accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255, uint32_t timebase = 0, uint8_t phase_offset = 0)
{
uint8_t beat = beat8(beats_per_minute, timebase);
uint8_t beatcos = cos8(beat + phase_offset);
uint8_t rangewidth = highest - lowest;
uint8_t scaledbeat = scale8(beatcos, rangewidth);
uint8_t result = lowest + scaledbeat;
return result;
}
uint8_t mapsin8(uint8_t theta, uint8_t lowest = 0, uint8_t highest = 255) {
uint8_t beatsin = sin8(theta);
uint8_t rangewidth = highest - lowest;
uint8_t scaledbeat = scale8(beatsin, rangewidth);
uint8_t result = lowest + scaledbeat;
return result;
}
uint8_t mapcos8(uint8_t theta, uint8_t lowest = 0, uint8_t highest = 255) {
uint8_t beatcos = cos8(theta);
uint8_t rangewidth = highest - lowest;
uint8_t scaledbeat = scale8(beatcos, rangewidth);
uint8_t result = lowest + scaledbeat;
return result;
}
// Array of temperature readings at each simulation cell
byte heat[NUM_LEDS];
uint32_t noise_x;
uint32_t noise_y;
uint32_t noise_z;
uint32_t noise_scale_x;
uint32_t noise_scale_y;
uint8_t noise[MATRIX_WIDTH][MATRIX_HEIGHT];
uint8_t noisesmoothing;
class Effects {
public:
//CRGB *leds;
CRGB leds[NUM_LEDS];
//CRGB leds2[NUM_LEDS]; // Faptastic: getting rid of this and any dependant effects or algos. to save memory 24*64*32 bytes of ram (50k).
/* The only 'framebuffer' we have is what is contained in the leds and leds2 variables.
* We don't store what the color a particular pixel might be, other than when it's turned
* into raw electrical signal output gobbly-gook (i.e. the DMA matrix buffer), but this * is not reversible.
*
* As such, any time these effects want to write a pixel color, we first have to update
* the leds or leds2 array, and THEN write it to the RGB panel. This enables us to 'look up' the array to see what a pixel color was previously, each drawFrame().
*/
void drawBackgroundFastLEDPixelCRGB(int16_t x, int16_t y, CRGB color)
{
leds[XY(x, y)] = color;
matrix.drawPixelRGB888(x, y, color.r, color.g, color.b);
}
// write one pixel with the specified color from the current palette to coordinates
void Pixel(int x, int y, uint8_t colorIndex) {
CRGB temp = ColorFromCurrentPalette(colorIndex);
leds[XY(x, y)] = temp;
matrix.drawPixelRGB888(x, y, temp.r, temp.g, temp.b); // now draw it?
}
void PrepareFrame() {
// leds = (CRGB*) backgroundLayer.backBuffer();
}
void ShowFrame() {
//#if (FASTLED_VERSION >= 3001000)
// nblendPaletteTowardPalette(currentPalette, targetPalette, 24);
//#else
currentPalette = targetPalette;
//#endif
// backgroundLayer.swapBuffers();
// leds = (CRGB*) backgroundLayer.backBuffer();
// LEDS.countFPS();
for (int y=0;y<MATRIX_HEIGHT; y++)
for (int x=0;x<MATRIX_WIDTH; x++)
{
CRGB tmp_led = leds[XY(x,y)];
//Serial.printf("\r\nFlushing x, y coord %d, %d", x, y);
//display.drawPixelRGB888( x, 31-y, tmp_led.r, tmp_led.g, tmp_led.b);
matrix.drawPixelRGB888( x, y, tmp_led.r, tmp_led.g, tmp_led.b);
} // end loop to copy fast led to the dma matrix
}
// scale the brightness of the screenbuffer down
void DimAll(byte value)
{
for (int i = 0; i < NUM_LEDS; i++)
{
leds[i].nscale8(value);
}
}
void ClearFrame()
{
memset(leds, 0x00, sizeof(leds)); // flush
}
/*
void CircleStream(uint8_t value) {
DimAll(value); ShowFrame();
for (uint8_t offset = 0; offset < MATRIX_CENTER_X; offset++) {
boolean hasprev = false;
uint16_t prevxy = 0;
for (uint8_t theta = 0; theta < 255; theta++) {
uint8_t x = mapcos8(theta, offset, (MATRIX_WIDTH - 1) - offset);
uint8_t y = mapsin8(theta, offset, (MATRIX_HEIGHT - 1) - offset);
uint16_t xy = XY(x, y);
if (hasprev) {
leds[prevxy] += leds[xy];
}
prevxy = xy;
hasprev = true;
}
}
for (uint8_t x = 0; x < MATRIX_WIDTH; x++) {
for (uint8_t y = 0; y < MATRIX_HEIGHT; y++) {
uint16_t xy = XY(x, y);
leds[xy] = leds2[xy];
leds[xy].nscale8(value);
leds2[xy].nscale8(value);
}
}
}
*/
// palettes
static const int paletteCount = 10;
int paletteIndex = -1;
TBlendType currentBlendType = LINEARBLEND;
CRGBPalette16 currentPalette;
CRGBPalette16 targetPalette;
char* currentPaletteName;
static const int HeatColorsPaletteIndex = 6;
static const int RandomPaletteIndex = 9;
void Setup() {
currentPalette = RainbowColors_p;
loadPalette(0);
NoiseVariablesSetup();
}
void CyclePalette(int offset = 1) {
loadPalette(paletteIndex + offset);
}
void RandomPalette() {
loadPalette(RandomPaletteIndex);
}
void loadPalette(int index) {
paletteIndex = index;
if (paletteIndex >= paletteCount)
paletteIndex = 0;
else if (paletteIndex < 0)
paletteIndex = paletteCount - 1;
switch (paletteIndex) {
case 0:
targetPalette = RainbowColors_p;
currentPaletteName = (char *)"Rainbow";
break;
//case 1:
// targetPalette = RainbowStripeColors_p;
// currentPaletteName = (char *)"RainbowStripe";
// break;
case 1:
targetPalette = OceanColors_p;
currentPaletteName = (char *)"Ocean";
break;
case 2:
targetPalette = CloudColors_p;
currentPaletteName = (char *)"Cloud";
break;
case 3:
targetPalette = ForestColors_p;
currentPaletteName = (char *)"Forest";
break;
case 4:
targetPalette = PartyColors_p;
currentPaletteName = (char *)"Party";
break;
case 5:
setupGrayscalePalette();
currentPaletteName = (char *)"Grey";
break;
case HeatColorsPaletteIndex:
targetPalette = HeatColors_p;
currentPaletteName = (char *)"Heat";
break;
case 7:
targetPalette = LavaColors_p;
currentPaletteName = (char *)"Lava";
break;
case 8:
setupIcePalette();
currentPaletteName = (char *)"Ice";
break;
case RandomPaletteIndex:
loadPalette(random(0, paletteCount - 1));
paletteIndex = RandomPaletteIndex;
currentPaletteName = (char *)"Random";
break;
}
}
void setPalette(String paletteName) {
if (paletteName == "Rainbow")
loadPalette(0);
//else if (paletteName == "RainbowStripe")
// loadPalette(1);
else if (paletteName == "Ocean")
loadPalette(1);
else if (paletteName == "Cloud")
loadPalette(2);
else if (paletteName == "Forest")
loadPalette(3);
else if (paletteName == "Party")
loadPalette(4);
else if (paletteName == "Grayscale")
loadPalette(5);
else if (paletteName == "Heat")
loadPalette(6);
else if (paletteName == "Lava")
loadPalette(7);
else if (paletteName == "Ice")
loadPalette(8);
else if (paletteName == "Random")
RandomPalette();
}
void listPalettes() {
Serial.println(F("{"));
Serial.print(F(" \"count\": "));
Serial.print(paletteCount);
Serial.println(",");
Serial.println(F(" \"results\": ["));
String paletteNames [] = {
"Rainbow",
// "RainbowStripe",
"Ocean",
"Cloud",
"Forest",
"Party",
"Grayscale",
"Heat",
"Lava",
"Ice",
"Random"
};
for (int i = 0; i < paletteCount; i++) {
Serial.print(F(" \""));
Serial.print(paletteNames[i]);
if (i == paletteCount - 1)
Serial.println(F("\""));
else
Serial.println(F("\","));
}
Serial.println(" ]");
Serial.println("}");
}
void setupGrayscalePalette() {
targetPalette = CRGBPalette16(CRGB::Black, CRGB::White);
}
void setupIcePalette() {
targetPalette = CRGBPalette16(CRGB::Black, CRGB::Blue, CRGB::Aqua, CRGB::White);
}
// Oscillators and Emitters
// the oscillators: linear ramps 0-255
byte osci[6];
// sin8(osci) swinging between 0 to MATRIX_WIDTH - 1
byte p[6];
// set the speeds (and by that ratios) of the oscillators here
void MoveOscillators() {
osci[0] = osci[0] + 5;
osci[1] = osci[1] + 2;
osci[2] = osci[2] + 3;
osci[3] = osci[3] + 4;
osci[4] = osci[4] + 1;
if (osci[4] % 2 == 0)
osci[5] = osci[5] + 1; // .5
for (int i = 0; i < 4; i++) {
p[i] = map8(sin8(osci[i]), 0, MATRIX_WIDTH - 1); //why? to keep the result in the range of 0-MATRIX_WIDTH (matrix size)
}
}
// All the caleidoscope functions work directly within the screenbuffer (leds array).
// Draw whatever you like in the area x(0-15) and y (0-15) and then copy it arround.
// rotates the first 16x16 quadrant 3 times onto a 32x32 (+90 degrees rotation for each one)
void Caleidoscope1() {
for (int x = 0; x < MATRIX_CENTER_X; x++) {
for (int y = 0; y < MATRIX_CENTER_Y; y++) {
leds[XY(MATRIX_WIDTH - 1 - x, y)] = leds[XY(x, y)];
leds[XY(MATRIX_WIDTH - 1 - x, MATRIX_HEIGHT - 1 - y)] = leds[XY(x, y)];
leds[XY(x, MATRIX_HEIGHT - 1 - y)] = leds[XY(x, y)];
}
}
}
// mirror the first 16x16 quadrant 3 times onto a 32x32
void Caleidoscope2() {
for (int x = 0; x < MATRIX_CENTER_X; x++) {
for (int y = 0; y < MATRIX_CENTER_Y; y++) {
leds[XY(MATRIX_WIDTH - 1 - x, y)] = leds[XY(y, x)];
leds[XY(x, MATRIX_HEIGHT - 1 - y)] = leds[XY(y, x)];
leds[XY(MATRIX_WIDTH - 1 - x, MATRIX_HEIGHT - 1 - y)] = leds[XY(x, y)];
}
}
}
// copy one diagonal triangle into the other one within a 16x16
void Caleidoscope3() {
for (int x = 0; x <= MATRIX_CENTRE_X; x++) {
for (int y = 0; y <= x; y++) {
leds[XY(x, y)] = leds[XY(y, x)];
}
}
}
// copy one diagonal triangle into the other one within a 16x16 (90 degrees rotated compared to Caleidoscope3)
void Caleidoscope4() {
for (int x = 0; x <= MATRIX_CENTRE_X; x++) {
for (int y = 0; y <= MATRIX_CENTRE_Y - x; y++) {
leds[XY(MATRIX_CENTRE_Y - y, MATRIX_CENTRE_X - x)] = leds[XY(x, y)];
}
}
}
// copy one diagonal triangle into the other one within a 8x8
void Caleidoscope5() {
for (int x = 0; x < MATRIX_WIDTH / 4; x++) {
for (int y = 0; y <= x; y++) {
leds[XY(x, y)] = leds[XY(y, x)];
}
}
for (int x = MATRIX_WIDTH / 4; x < MATRIX_WIDTH / 2; x++) {
for (int y = MATRIX_HEIGHT / 4; y >= 0; y--) {
leds[XY(x, y)] = leds[XY(y, x)];
}
}
}
void Caleidoscope6() {
for (int x = 1; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 7)] = leds[XY(x, 0)];
} //a
for (int x = 2; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 6)] = leds[XY(x, 1)];
} //b
for (int x = 3; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 5)] = leds[XY(x, 2)];
} //c
for (int x = 4; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 4)] = leds[XY(x, 3)];
} //d
for (int x = 5; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 3)] = leds[XY(x, 4)];
} //e
for (int x = 6; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 2)] = leds[XY(x, 5)];
} //f
for (int x = 7; x < MATRIX_CENTER_X; x++) {
leds[XY(7 - x, 1)] = leds[XY(x, 6)];
} //g
}
// create a square twister to the left or counter-clockwise
// x and y for center, r for radius
void SpiralStream(int x, int y, int r, byte dimm) {
for (int d = r; d >= 0; d--) { // from the outside to the inside
for (int i = x - d; i <= x + d; i++) {
leds[XY(i, y - d)] += leds[XY(i + 1, y - d)]; // lowest row to the right
leds[XY(i, y - d)].nscale8(dimm);
}
for (int i = y - d; i <= y + d; i++) {
leds[XY(x + d, i)] += leds[XY(x + d, i + 1)]; // right colum up
leds[XY(x + d, i)].nscale8(dimm);
}
for (int i = x + d; i >= x - d; i--) {
leds[XY(i, y + d)] += leds[XY(i - 1, y + d)]; // upper row to the left
leds[XY(i, y + d)].nscale8(dimm);
}
for (int i = y + d; i >= y - d; i--) {
leds[XY(x - d, i)] += leds[XY(x - d, i - 1)]; // left colum down
leds[XY(x - d, i)].nscale8(dimm);
}
}
}
// expand everything within a circle
void Expand(int centerX, int centerY, int radius, byte dimm) {
if (radius == 0)
return;
int currentRadius = radius;
while (currentRadius > 0) {
int a = radius, b = 0;
int radiusError = 1 - a;
int nextRadius = currentRadius - 1;
int nextA = nextRadius - 1, nextB = 0;
int nextRadiusError = 1 - nextA;
while (a >= b)
{
// move them out one pixel on the radius
leds[XY(a + centerX, b + centerY)] = leds[XY(nextA + centerX, nextB + centerY)];
leds[XY(b + centerX, a + centerY)] = leds[XY(nextB + centerX, nextA + centerY)];
leds[XY(-a + centerX, b + centerY)] = leds[XY(-nextA + centerX, nextB + centerY)];
leds[XY(-b + centerX, a + centerY)] = leds[XY(-nextB + centerX, nextA + centerY)];
leds[XY(-a + centerX, -b + centerY)] = leds[XY(-nextA + centerX, -nextB + centerY)];
leds[XY(-b + centerX, -a + centerY)] = leds[XY(-nextB + centerX, -nextA + centerY)];
leds[XY(a + centerX, -b + centerY)] = leds[XY(nextA + centerX, -nextB + centerY)];
leds[XY(b + centerX, -a + centerY)] = leds[XY(nextB + centerX, -nextA + centerY)];
// dim them
leds[XY(a + centerX, b + centerY)].nscale8(dimm);
leds[XY(b + centerX, a + centerY)].nscale8(dimm);
leds[XY(-a + centerX, b + centerY)].nscale8(dimm);
leds[XY(-b + centerX, a + centerY)].nscale8(dimm);
leds[XY(-a + centerX, -b + centerY)].nscale8(dimm);
leds[XY(-b + centerX, -a + centerY)].nscale8(dimm);
leds[XY(a + centerX, -b + centerY)].nscale8(dimm);
leds[XY(b + centerX, -a + centerY)].nscale8(dimm);
b++;
if (radiusError < 0)
radiusError += 2 * b + 1;
else
{
a--;
radiusError += 2 * (b - a + 1);
}
nextB++;
if (nextRadiusError < 0)
nextRadiusError += 2 * nextB + 1;
else
{
nextA--;
nextRadiusError += 2 * (nextB - nextA + 1);
}
}
currentRadius--;
}
}
// give it a linear tail to the right
void StreamRight(byte scale, int fromX = 0, int toX = MATRIX_WIDTH, int fromY = 0, int toY = MATRIX_HEIGHT)
{
for (int x = fromX + 1; x < toX; x++) {
for (int y = fromY; y < toY; y++) {
leds[XY(x, y)] += leds[XY(x - 1, y)];
leds[XY(x, y)].nscale8(scale);
}
}
for (int y = fromY; y < toY; y++)
leds[XY(0, y)].nscale8(scale);
}
// give it a linear tail to the left
void StreamLeft(byte scale, int fromX = MATRIX_WIDTH, int toX = 0, int fromY = 0, int toY = MATRIX_HEIGHT)
{
for (int x = toX; x < fromX; x++) {
for (int y = fromY; y < toY; y++) {
leds[XY(x, y)] += leds[XY(x + 1, y)];
leds[XY(x, y)].nscale8(scale);
}
}
for (int y = fromY; y < toY; y++)
leds[XY(0, y)].nscale8(scale);
}
// give it a linear tail downwards
void StreamDown(byte scale)
{
for (int x = 0; x < MATRIX_WIDTH; x++) {
for (int y = 1; y < MATRIX_HEIGHT; y++) {
leds[XY(x, y)] += leds[XY(x, y - 1)];
leds[XY(x, y)].nscale8(scale);
}
}
for (int x = 0; x < MATRIX_WIDTH; x++)
leds[XY(x, 0)].nscale8(scale);
}
// give it a linear tail upwards
void StreamUp(byte scale)
{
for (int x = 0; x < MATRIX_WIDTH; x++) {
for (int y = MATRIX_HEIGHT - 2; y >= 0; y--) {
leds[XY(x, y)] += leds[XY(x, y + 1)];
leds[XY(x, y)].nscale8(scale);
}
}
for (int x = 0; x < MATRIX_WIDTH; x++)
leds[XY(x, MATRIX_HEIGHT - 1)].nscale8(scale);
}
// give it a linear tail up and to the left
void StreamUpAndLeft(byte scale)
{
for (int x = 0; x < MATRIX_WIDTH - 1; x++) {
for (int y = MATRIX_HEIGHT - 2; y >= 0; y--) {
leds[XY(x, y)] += leds[XY(x + 1, y + 1)];
leds[XY(x, y)].nscale8(scale);
}
}
for (int x = 0; x < MATRIX_WIDTH; x++)
leds[XY(x, MATRIX_HEIGHT - 1)].nscale8(scale);
for (int y = 0; y < MATRIX_HEIGHT; y++)
leds[XY(MATRIX_WIDTH - 1, y)].nscale8(scale);
}
// give it a linear tail up and to the right
void StreamUpAndRight(byte scale)
{
for (int x = 0; x < MATRIX_WIDTH - 1; x++) {
for (int y = MATRIX_HEIGHT - 2; y >= 0; y--) {
leds[XY(x + 1, y)] += leds[XY(x, y + 1)];
leds[XY(x, y)].nscale8(scale);
}
}
// fade the bottom row
for (int x = 0; x < MATRIX_WIDTH; x++)
leds[XY(x, MATRIX_HEIGHT - 1)].nscale8(scale);
// fade the right column
for (int y = 0; y < MATRIX_HEIGHT; y++)
leds[XY(MATRIX_WIDTH - 1, y)].nscale8(scale);
}
// just move everything one line down
void MoveDown() {
for (int y = MATRIX_HEIGHT - 1; y > 0; y--) {
for (int x = 0; x < MATRIX_WIDTH; x++) {
leds[XY(x, y)] = leds[XY(x, y - 1)];
}
}
}
// just move everything one line down
void VerticalMoveFrom(int start, int end) {
for (int y = end; y > start; y--) {
for (int x = 0; x < MATRIX_WIDTH; x++) {
leds[XY(x, y)] = leds[XY(x, y - 1)];
}
}
}
// copy the rectangle defined with 2 points x0, y0, x1, y1
// to the rectangle beginning at x2, x3
void Copy(byte x0, byte y0, byte x1, byte y1, byte x2, byte y2) {
for (int y = y0; y < y1 + 1; y++) {
for (int x = x0; x < x1 + 1; x++) {
leds[XY(x + x2 - x0, y + y2 - y0)] = leds[XY(x, y)];
}
}
}
// rotate + copy triangle (MATRIX_CENTER_X*MATRIX_CENTER_X)
void RotateTriangle() {
for (int x = 1; x < MATRIX_CENTER_X; x++) {
for (int y = 0; y < x; y++) {
leds[XY(x, 7 - y)] = leds[XY(7 - x, y)];
}
}
}
// mirror + copy triangle (MATRIX_CENTER_X*MATRIX_CENTER_X)
void MirrorTriangle() {
for (int x = 1; x < MATRIX_CENTER_X; x++) {
for (int y = 0; y < x; y++) {
leds[XY(7 - y, x)] = leds[XY(7 - x, y)];
}
}
}
// draw static rainbow triangle pattern (MATRIX_CENTER_XxWIDTH / 2)
// (just for debugging)
void RainbowTriangle() {
for (int i = 0; i < MATRIX_CENTER_X; i++) {
for (int j = 0; j <= i; j++) {
Pixel(7 - i, j, i * j * 4);
}
}
}
void BresenhamLine(int x0, int y0, int x1, int y1, byte colorIndex)
{
BresenhamLine(x0, y0, x1, y1, ColorFromCurrentPalette(colorIndex));
}
void BresenhamLine(int x0, int y0, int x1, int y1, CRGB color)
{
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
int err = dx + dy, e2;
for (;;) {
leds[XY(x0, y0)] += color;
if (x0 == x1 && y0 == y1) break;
e2 = 2 * err;
if (e2 > dy) {
err += dy;
x0 += sx;
}
if (e2 < dx) {
err += dx;
y0 += sy;
}
}
}
// write one pixel with the specified color from the current palette to coordinates
/*
void Pixel(int x, int y, uint8_t colorIndex) {
leds[XY(x, y)] = ColorFromCurrentPalette(colorIndex);
matrix.drawBackgroundPixelRGB888(x,y, leds[XY(x, y)]); // now draw it?
}
*/
CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) {
return ColorFromPalette(currentPalette, index, brightness, currentBlendType);
}
CRGB HsvToRgb(uint8_t h, uint8_t s, uint8_t v) {
CHSV hsv = CHSV(h, s, v);
CRGB rgb;
hsv2rgb_spectrum(hsv, rgb);
return rgb;
}
void NoiseVariablesSetup() {
noisesmoothing = 200;
noise_x = random16();
noise_y = random16();
noise_z = random16();
noise_scale_x = 6000;
noise_scale_y = 6000;
}
void FillNoise() {
for (uint8_t i = 0; i < MATRIX_WIDTH; i++) {
uint32_t ioffset = noise_scale_x * (i - MATRIX_CENTRE_Y);
for (uint8_t j = 0; j < MATRIX_HEIGHT; j++) {
uint32_t joffset = noise_scale_y * (j - MATRIX_CENTRE_Y);
byte data = inoise16(noise_x + ioffset, noise_y + joffset, noise_z) >> 8;
uint8_t olddata = noise[i][j];
uint8_t newdata = scale8(olddata, noisesmoothing) + scale8(data, 256 - noisesmoothing);
data = newdata;
noise[i][j] = data;
}
}
}
// non leds2 memory version.
void MoveX(byte delta)
{
CRGB tmp = 0;
for (int y = 0; y < MATRIX_HEIGHT; y++)
{
// Shift Left: https://codedost.com/c/arraypointers-in-c/c-program-shift-elements-array-left-direction/
// Computationally heavier but doesn't need an entire leds2 array
tmp = leds[XY(0, y)];
for (int m = 0; m < delta; m++)
{
// Do this delta time for each row... computationally expensive potentially.
for(int x = 0; x < MATRIX_WIDTH; x++)
{
leds[XY(x, y)] = leds [XY(x+1, y)];
}
leds[XY(MATRIX_WIDTH-1, y)] = tmp;
}
/*
// Shift
for (int x = 0; x < MATRIX_WIDTH - delta; x++) {
leds2[XY(x, y)] = leds[XY(x + delta, y)];
}
// Wrap around
for (int x = MATRIX_WIDTH - delta; x < MATRIX_WIDTH; x++) {
leds2[XY(x, y)] = leds[XY(x + delta - MATRIX_WIDTH, y)];
}
*/
} // end row loop
/*
// write back to leds
for (uint8_t y = 0; y < MATRIX_HEIGHT; y++) {
for (uint8_t x = 0; x < MATRIX_WIDTH; x++) {
leds[XY(x, y)] = leds2[XY(x, y)];
}
}
*/
}
void MoveY(byte delta)
{
CRGB tmp = 0;
for (int x = 0; x < MATRIX_WIDTH; x++)
{
tmp = leds[XY(x, 0)];
for (int m = 0; m < delta; m++) // moves
{
// Do this delta time for each row... computationally expensive potentially.
for(int y = 0; y < MATRIX_HEIGHT; y++)
{
leds[XY(x, y)] = leds [XY(x, y+1)];
}
leds[XY(x, MATRIX_HEIGHT-1)] = tmp;
}
} // end column loop
} /// MoveY
};
#endif

View file

@ -0,0 +1,150 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from Noel Bundy's work: https://github.com/TwystNeko/Object3d
* Copyright (c) 2014 Noel Bundy
*
* Portions of this code are adapted from the Petty library: https://code.google.com/p/peggy/
* Copyright (c) 2008 Windell H Oskay. All right reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef Geometry_H
#define Geometry_H
struct Vertex
{
float x, y, z;
Vertex()
{
this->set(0, 0, 0);
}
Vertex(float x, float y, float z)
{
this->set(x, y, z);
}
void set(float x, float y, float z)
{
this->x = x;
this->y = y;
this->z = z;
}
};
struct EdgePoint
{
int x, y;
boolean visible;
EdgePoint()
{
this->set(0, 0);
this->visible = false;
}
void set(int a, int b)
{
this->x = a;
this->y = b;
}
};
struct Point
{
float x, y;
Point()
{
set(0, 0);
}
Point(float x, float y)
{
set(x, y);
}
void set(float x, float y)
{
this->x = x;
this->y = y;
}
};
struct squareFace
{
int length;
int sommets[4];
int ed[4];
squareFace()
{
set(-1, -1, -1, -1);
}
squareFace(int a, int b, int c, int d)
{
this->length = 4;
this->sommets[0] = a;
this->sommets[1] = b;
this->sommets[2] = c;
this->sommets[3] = d;
}
void set(int a, int b, int c, int d)
{
this->length = 4;
this->sommets[0] = a;
this->sommets[1] = b;
this->sommets[2] = c;
this->sommets[3] = d;
}
};
struct triFace
{
int length;
int sommets[3];
int ed[3];
triFace()
{
set(-1,-1,-1);
}
triFace(int a, int b, int c)
{
this->length =3;
this->sommets[0]=a;
this->sommets[1]=b;
this->sommets[2]=c;
}
void set(int a, int b, int c)
{
this->length =3;
this->sommets[0]=a;
this->sommets[1]=b;
this->sommets[2]=c;
}
};
#endif

View file

@ -0,0 +1,73 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternAttract_H
class PatternAttract : public Drawable {
private:
const int count = 8;
Attractor attractor;
public:
PatternAttract() {
name = (char *)"Attract";
}
void start() {
int direction = random(0, 2);
if (direction == 0)
direction = -1;
for (int i = 0; i < count; i++) {
Boid boid = Boid(15, 31 - i);
boid.mass = 1; // random(0.1, 2);
boid.velocity.x = ((float) random(40, 50)) / 100.0;
boid.velocity.x *= direction;
boid.velocity.y = 0;
boid.colorIndex = i * 32;
boids[i] = boid;
//dim = random(170, 250);
}
}
unsigned int drawFrame() {
// dim all pixels on the display
uint8_t dim = beatsin8(2, 170, 250);
effects.DimAll(dim); effects.ShowFrame();
for (int i = 0; i < count; i++) {
Boid boid = boids[i];
PVector force = attractor.attract(boid);
boid.applyForce(force);
boid.update();
effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex));
boids[i] = boid;
}
return 15;
}
};
#endif

View file

@ -0,0 +1,73 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternBounce_H
class PatternBounce : public Drawable {
private:
static const int count = 32;
PVector gravity = PVector(0, 0.0125);
public:
PatternBounce() {
name = (char *)"Bounce";
}
void start() {
unsigned int colorWidth = 256 / count;
for (int i = 0; i < count; i++) {
Boid boid = Boid(i, 0);
boid.velocity.x = 0;
boid.velocity.y = i * -0.01;
boid.colorIndex = colorWidth * i;
boid.maxforce = 10;
boid.maxspeed = 10;
boids[i] = boid;
}
}
unsigned int drawFrame() {
// dim all pixels on the display
effects.DimAll(170); effects.ShowFrame();
for (int i = 0; i < count; i++) {
Boid boid = boids[i];
boid.applyForce(gravity);
boid.update();
effects.drawBackgroundFastLEDPixelCRGB(boid.location.x, boid.location.y, effects.ColorFromCurrentPalette(boid.colorIndex));
if (boid.location.y >= MATRIX_HEIGHT - 1) {
boid.location.y = MATRIX_HEIGHT - 1;
boid.velocity.y *= -1.0;
}
boids[i] = boid;
}
return 15;
}
};
#endif

View file

@ -0,0 +1,219 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from Noel Bundy's work: https://github.com/TwystNeko/Object3d
* Copyright (c) 2014 Noel Bundy
*
* Portions of this code are adapted from the Petty library: https://code.google.com/p/peggy/
* Copyright (c) 2008 Windell H Oskay. All right reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternCube_H
#define PatternCube_H
class PatternCube : public Drawable {
private:
float focal = 30; // Focal of the camera
int cubeWidth = 28; // Cube size
float Angx = 20.0, AngxSpeed = 0.05; // rotation (angle+speed) around X-axis
float Angy = 10.0, AngySpeed = 0.05; // rotation (angle+speed) around Y-axis
float Ox = 15.5, Oy = 15.5; // position (x,y) of the frame center
int zCamera = 110; // distance from cube to the eye of the camera
// Local vertices
Vertex local[8];
// Camera aligned vertices
Vertex aligned[8];
// On-screen projected vertices
Point screen[8];
// Faces
squareFace face[6];
// Edges
EdgePoint edge[12];
int nbEdges;
// ModelView matrix
float m00, m01, m02, m10, m11, m12, m20, m21, m22;
// constructs the cube
void make(int w)
{
nbEdges = 0;
local[0].set(-w, w, w);
local[1].set(w, w, w);
local[2].set(w, -w, w);
local[3].set(-w, -w, w);
local[4].set(-w, w, -w);
local[5].set(w, w, -w);
local[6].set(w, -w, -w);
local[7].set(-w, -w, -w);
face[0].set(1, 0, 3, 2);
face[1].set(0, 4, 7, 3);
face[2].set(4, 0, 1, 5);
face[3].set(4, 5, 6, 7);
face[4].set(1, 2, 6, 5);
face[5].set(2, 3, 7, 6);
int f, i;
for (f = 0; f < 6; f++)
{
for (i = 0; i < face[f].length; i++)
{
face[f].ed[i] = this->findEdge(face[f].sommets[i], face[f].sommets[i ? i - 1 : face[f].length - 1]);
}
}
}
// finds edges from faces
int findEdge(int a, int b)
{
int i;
for (i = 0; i < nbEdges; i++)
if ((edge[i].x == a && edge[i].y == b) || (edge[i].x == b && edge[i].y == a))
return i;
edge[nbEdges++].set(a, b);
return i;
}
// rotates according to angle x&y
void rotate(float angx, float angy)
{
int i;
float cx = cos(angx);
float sx = sin(angx);
float cy = cos(angy);
float sy = sin(angy);
m00 = cy;
m01 = 0;
m02 = -sy;
m10 = sx * sy;
m11 = cx;
m12 = sx * cy;
m20 = cx * sy;
m21 = -sx;
m22 = cx * cy;
for (i = 0; i < 8; i++)
{
aligned[i].x = m00 * local[i].x + m01 * local[i].y + m02 * local[i].z;
aligned[i].y = m10 * local[i].x + m11 * local[i].y + m12 * local[i].z;
aligned[i].z = m20 * local[i].x + m21 * local[i].y + m22 * local[i].z + zCamera;
screen[i].x = floor((Ox + focal * aligned[i].x / aligned[i].z));
screen[i].y = floor((Oy - focal * aligned[i].y / aligned[i].z));
}
for (i = 0; i < 12; i++)
edge[i].visible = false;
Point *pa, *pb, *pc;
for (i = 0; i < 6; i++)
{
pa = screen + face[i].sommets[0];
pb = screen + face[i].sommets[1];
pc = screen + face[i].sommets[2];
boolean back = ((pb->x - pa->x) * (pc->y - pa->y) - (pb->y - pa->y) * (pc->x - pa->x)) < 0;
if (!back)
{
int j;
for (j = 0; j < 4; j++)
{
edge[face[i].ed[j]].visible = true;
}
}
}
}
byte hue = 0;
int step = 0;
public:
PatternCube() {
name = (char *)"Cube";
make(cubeWidth);
}
unsigned int drawFrame() {
uint8_t blurAmount = beatsin8(2, 10, 255);
#if FASTLED_VERSION >= 3001000
blur2d(effects.leds, MATRIX_WIDTH, MATRIX_HEIGHT, blurAmount);
#else
effects.DimAll(blurAmount); effects.ShowFrame();
#endif
zCamera = beatsin8(2, 100, 140);
AngxSpeed = beatsin8(3, 1, 10) / 100.0f;
AngySpeed = beatcos8(5, 1, 10) / 100.0f;
// Update values
Angx += AngxSpeed;
Angy += AngySpeed;
if (Angx >= TWO_PI)
Angx -= TWO_PI;
if (Angy >= TWO_PI)
Angy -= TWO_PI;
rotate(Angx, Angy);
// Draw cube
int i;
CRGB color = effects.ColorFromCurrentPalette(hue, 128);
// Backface
EdgePoint *e;
for (i = 0; i < 12; i++)
{
e = edge + i;
if (!e->visible) {
matrix.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
}
}
color = effects.ColorFromCurrentPalette(hue, 255);
// Frontface
for (i = 0; i < 12; i++)
{
e = edge + i;
if (e->visible)
{
matrix.drawLine(screen[e->x].x, screen[e->x].y, screen[e->y].x, screen[e->y].y, color);
}
}
step++;
if (step == 8) {
step = 0;
hue++;
}
effects.ShowFrame();
return 20;
}
};
#endif

View file

@ -0,0 +1,116 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from "Funky Noise" by Stefan Petrick: https://github.com/StefanPetrick/FunkyNoise
* Copyright (c) 2014 Stefan Petrick
* http://www.stefan-petrick.de/wordpress_beta
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternElectricMandala_H
class PatternElectricMandala : public Drawable {
private:
// The coordinates for 16-bit noise spaces.
#define NUM_LAYERS 1
// used for the random based animations
int16_t dx;
int16_t dy;
int16_t dz;
int16_t dsx;
int16_t dsy;
public:
PatternElectricMandala() {
name = (char *)"ElectricMandala";
}
void start() {
// set to reasonable values to avoid a black out
noisesmoothing = 200;
// just any free input pin
//random16_add_entropy(analogRead(18));
// fill coordinates with random values
// set zoom levels
noise_x = random16();
noise_y = random16();
noise_z = random16();
noise_scale_x = 6000;
noise_scale_y = 6000;
// for the random movement
dx = random8();
dy = random8();
dz = random8();
dsx = random8();
dsy = random8();
}
unsigned int drawFrame() {
#if FASTLED_VERSION >= 3001000
// a new parameter set every 15 seconds
EVERY_N_SECONDS(15) {
//SetupRandomPalette3();
dy = random16(500) - 250; // random16(2000) - 1000 is pretty fast but works fine, too
dx = random16(500) - 250;
dz = random16(500) - 250;
noise_scale_x = random16(10000) + 2000;
noise_scale_y = random16(10000) + 2000;
}
#endif
noise_y += dy;
noise_x += dx;
noise_z += dz;
effects.FillNoise();
ShowNoiseLayer(0, 1, 0);
effects.Caleidoscope3();
effects.Caleidoscope1();
effects.ShowFrame();
return 0;
}
// show just one layer
void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) {
for (uint8_t i = 0; i < MATRIX_WIDTH; i++) {
for (uint8_t j = 0; j < MATRIX_HEIGHT; j++) {
uint8_t color = noise[i][j];
uint8_t bri = color;
// assign a color depending on the actual palette
CRGB pixel = ColorFromPalette(effects.currentPalette, colorrepeat * (color + colorshift), bri);
effects.leds[XY(i, j)] = pixel;
}
}
}
};
#endif

View file

@ -0,0 +1,118 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette
* Copyright (c) 2013 FastLED
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternFire_H
#define PatternFire_H
#ifndef Effects_H
#include "Effects.h"
#endif
class PatternFire : public Drawable {
private:
public:
PatternFire() {
name = (char *)"Fire";
}
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// cooling: How much does the air cool as it rises?
// Less cooling = taller flames. More cooling = shorter flames.
// Default 55, suggested range 20-100
int cooling = 100;
// sparking: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire. Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
unsigned int sparking = 100;
unsigned int drawFrame() {
// Add entropy to random number generator; we use a lot of it.
random16_add_entropy( random16());
effects.DimAll(235);
for (int x = 0; x < MATRIX_WIDTH; x++) {
// Step 1. Cool down every cell a little
for (int y = 0; y < MATRIX_HEIGHT; y++) {
int xy = XY(x, y);
heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / MATRIX_HEIGHT) + 2));
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for (int y = 0; y < MATRIX_HEIGHT; y++) {
heat[XY(x, y)] = (heat[XY(x, y + 1)] + heat[XY(x, y + 2)] + heat[XY(x, y + 2)]) / 3;
}
// Step 2. Randomly ignite new 'sparks' of heat
if (random8() < sparking) {
// int x = (p[0] + p[1] + p[2]) / 3;
int xy = XY(x, MATRIX_HEIGHT - 1);
heat[xy] = qadd8(heat[xy], random8(160, 255));
}
// Step 4. Map from heat cells to LED colors
for (int y = 0; y < MATRIX_HEIGHT; y++) {
int xy = XY(x, y);
byte colorIndex = heat[xy];
// Recommend that you use values 0-240 rather than
// the usual 0-255, as the last 15 colors will be
// 'wrapping around' from the hot end to the cold end,
// which looks wrong.
colorIndex = scale8(colorIndex, 200);
// override color 0 to ensure a black background?
if (colorIndex != 0)
// effects.leds[xy] = CRGB::Black;
// else
effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex);
}
}
// Noise
noise_x += 1000;
noise_y += 1000;
noise_z += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(2);
effects.MoveFractionalNoiseX(2);
effects.ShowFrame();
return 15;
}
};
#endif

View file

@ -0,0 +1,125 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from "Flocking" in "The Nature of Code" by Daniel Shiffman: http://natureofcode.com/
* Copyright (c) 2014 Daniel Shiffman
* http://www.shiffman.net
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// Flocking
// Daniel Shiffman <http://www.shiffman.net>
// The Nature of Code, Spring 2009
// Demonstration of Craig Reynolds' "Flocking" behavior
// See: http://www.red3d.com/cwr/
// Rules: Cohesion, Separation, Alignment
#ifndef PatternFlock_H
#define PatternFlock_H
class PatternFlock : public Drawable {
public:
PatternFlock() {
name = (char *)"Flock";
}
static const int boidCount = 10;
Boid predator;
PVector wind;
byte hue = 0;
bool predatorPresent = true;
void start() {
for (int i = 0; i < boidCount; i++) {
boids[i] = Boid(15, 15);
boids[i].maxspeed = 0.380;
boids[i].maxforce = 0.015;
}
predatorPresent = random(0, 2) >= 1;
if (predatorPresent) {
predator = Boid(31, 31);
predatorPresent = true;
predator.maxspeed = 0.385;
predator.maxforce = 0.020;
predator.neighbordist = 16.0;
predator.desiredseparation = 0.0;
}
}
unsigned int drawFrame() {
effects.DimAll(230); effects.ShowFrame();
bool applyWind = random(0, 255) > 250;
if (applyWind) {
wind.x = Boid::randomf() * .015;
wind.y = Boid::randomf() * .015;
}
CRGB color = effects.ColorFromCurrentPalette(hue);
for (int i = 0; i < boidCount; i++) {
Boid * boid = &boids[i];
if (predatorPresent) {
// flee from predator
boid->repelForce(predator.location, 10);
}
boid->run(boids, boidCount);
boid->wrapAroundBorders();
PVector location = boid->location;
// PVector velocity = boid->velocity;
// backgroundLayer.drawLine(location.x, location.y, location.x - velocity.x, location.y - velocity.y, color);
// effects.leds[XY(location.x, location.y)] += color;
effects.drawBackgroundFastLEDPixelCRGB(location.x, location.y, color);
if (applyWind) {
boid->applyForce(wind);
applyWind = false;
}
}
if (predatorPresent) {
predator.run(boids, boidCount);
predator.wrapAroundBorders();
color = effects.ColorFromCurrentPalette(hue + 128);
PVector location = predator.location;
// PVector velocity = predator.velocity;
// backgroundLayer.drawLine(location.x, location.y, location.x - velocity.x, location.y - velocity.y, color);
// effects.leds[XY(location.x, location.y)] += color;
effects.drawBackgroundFastLEDPixelCRGB(location.x, location.y, color);
}
EVERY_N_MILLIS(200) {
hue++;
}
EVERY_N_SECONDS(30) {
predatorPresent = !predatorPresent;
}
return 0;
}
};
#endif

View file

@ -0,0 +1,92 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternFlowField_H
class PatternFlowField : public Drawable {
public:
PatternFlowField() {
name = (char *)"FlowField";
}
uint16_t x;
uint16_t y;
uint16_t z;
uint16_t speed = 1;
uint16_t scale = 26;
static const int count = 40;
byte hue = 0;
void start() {
x = random16();
y = random16();
z = random16();
for (int i = 0; i < count; i++) {
boids[i] = Boid(random(MATRIX_WIDTH), 0);
}
}
unsigned int drawFrame() {
effects.DimAll(240);
// CRGB color = effects.ColorFromCurrentPalette(hue);
for (int i = 0; i < count; i++) {
Boid * boid = &boids[i];
int ioffset = scale * boid->location.x;
int joffset = scale * boid->location.y;
byte angle = inoise8(x + ioffset, y + joffset, z);
boid->velocity.x = (float) sin8(angle) * 0.0078125 - 1.0;
boid->velocity.y = -((float)cos8(angle) * 0.0078125 - 1.0);
boid->update();
effects.drawBackgroundFastLEDPixelCRGB(boid->location.x, boid->location.y, effects.ColorFromCurrentPalette(angle + hue)); // color
if (boid->location.x < 0 || boid->location.x >= MATRIX_WIDTH ||
boid->location.y < 0 || boid->location.y >= MATRIX_HEIGHT) {
boid->location.x = random(MATRIX_WIDTH);
boid->location.y = 0;
}
}
EVERY_N_MILLIS(200) {
hue++;
}
x += speed;
y += speed;
z += speed;
effects.ShowFrame();
return 50;
}
};
#endif

View file

@ -0,0 +1,51 @@
/*
*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternIncrementalDrift_H
#define PatternIncrementalDrift_H
class PatternIncrementalDrift : public Drawable {
public:
PatternIncrementalDrift() {
name = (char *)"Incremental Drift";
}
unsigned int drawFrame() {
uint8_t dim = beatsin8(2, 230, 250);
effects.DimAll(dim); effects.ShowFrame();
for (int i = 2; i <= MATRIX_WIDTH / 2; i++)
{
CRGB color = effects.ColorFromCurrentPalette((i - 2) * (240 / (MATRIX_WIDTH / 2)));
uint8_t x = beatcos8((17 - i) * 2, MATRIX_CENTER_X - i, MATRIX_CENTER_X + i);
uint8_t y = beatsin8((17 - i) * 2, MATRIX_CENTER_Y - i, MATRIX_CENTER_Y + i);
effects.drawBackgroundFastLEDPixelCRGB(x, y, color);
}
return 0;
}
};
#endif

View file

@ -0,0 +1,63 @@
/*
*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternIncrementalDrift2_H
#define PatternIncrementalDrift2_H
class PatternIncrementalDrift2 : public Drawable {
public:
PatternIncrementalDrift2() {
name = (char *)"Incremental Drift Rose";
}
unsigned int drawFrame() {
uint8_t dim = beatsin8(2, 170, 250);
effects.DimAll(dim); effects.ShowFrame();
for (uint8_t i = 0; i < 32; i++)
{
CRGB color;
uint8_t x = 0;
uint8_t y = 0;
if (i < 16) {
x = beatcos8((i + 1) * 2, i, MATRIX_WIDTH - i);
y = beatsin8((i + 1) * 2, i, MATRIX_HEIGHT - i);
color = effects.ColorFromCurrentPalette(i * 14);
}
else
{
x = beatsin8((32 - i) * 2, MATRIX_WIDTH - i, i + 1);
y = beatcos8((32 - i) * 2, MATRIX_HEIGHT - i, i + 1);
color = effects.ColorFromCurrentPalette((31 - i) * 14);
}
effects.drawBackgroundFastLEDPixelCRGB(x, y, color);
}
return 0;
}
};
#endif

View file

@ -0,0 +1,58 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternInfinity_H
class PatternInfinity : public Drawable {
public:
PatternInfinity() {
name = (char *)"Infinity";
}
unsigned int drawFrame() {
// dim all pixels on the display slightly
// to 250/255 (98%) of their current brightness
effects.DimAll(250); effects.ShowFrame();
// the Effects class has some sample oscillators
// that move from 0 to 255 at different speeds
effects.MoveOscillators();
// the horizontal position of the head of the infinity sign
// oscillates from 0 to the maximum horizontal and back
int x = (MATRIX_WIDTH - 1) - effects.p[1];
// the vertical position of the head oscillates
// from 8 to 23 and back (hard-coded for a 32x32 matrix)
int y = map8(sin8(effects.osci[3]), 8, 23);
// the hue oscillates from 0 to 255, overflowing back to 0
byte hue = sin8(effects.osci[5]);
// draw a pixel at x,y using a color from the current palette
effects.Pixel(x, y, hue);
return 15;
}
};
#endif

View file

@ -0,0 +1,154 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Inspired by 'Space Invader Generator': https://the8bitpimp.wordpress.com/2013/05/07/space-invader-generator
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternInvaders_H
#define PatternInvaders_H
class PatternInvadersSmall : public Drawable {
private:
uint8_t x = 1;
uint8_t y = 1;
public:
PatternInvadersSmall() {
name = (char *)"Invaders Small";
}
void start() {
matrix.fillScreen(0);
}
unsigned int drawFrame() {
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
CRGB color = CRGB::Black;
if (random(0, 2) == 1) color = color1;
effects.drawBackgroundFastLEDPixelCRGB(x + i, y + j, color);
if (i < 2)
effects.drawBackgroundFastLEDPixelCRGB(x + (4 - i), y + j, color);
}
}
x += 6;
if (x > 25) {
x = 1;
y += 6;
}
if (y > 25) y = x = 1;
effects.ShowFrame();
return 125;
}
};
class PatternInvadersMedium : public Drawable {
private:
uint8_t x = 0;
uint8_t y = 0;
public:
PatternInvadersMedium() {
name = (char *)"Invaders Medium";
}
void start() {
matrix.fillScreen(0);
}
unsigned int drawFrame() {
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 5; j++) {
CRGB color = CRGB::Black;
if (random(0, 2) == 1) color = color1;
matrix.fillRect(x + (i * 2), y + (j * 2), x + (i * 2 + 1), y + (j * 2 + 1), color);
if (i < 2)
matrix.fillRect(x + (8 - i * 2), y + (j * 2), x + (9 - i * 2), y + (j * 2 + 1), color);
}
}
x += 11;
if (x > 22) {
x = 0;
y += 11;
}
if (y > 22) y = x = 0;
effects.ShowFrame();
return 500;
}
};
class PatternInvadersLarge : public Drawable {
private:
public:
PatternInvadersLarge() {
name = (char *)"Invaders Large";
}
void start() {
matrix.fillScreen(0);
}
unsigned int drawFrame() {
matrix.fillScreen(0);
CRGB color1 = effects.ColorFromCurrentPalette(random(0, 255));
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 5; y++) {
CRGB color = CRGB::Black;
if (random(0, 2) == 1) {
color = color1;
}
matrix.fillRect(1 + x * 6, 1 + y * 6, 5 + x * 6, 5 + y * 6, color);
if (x < 2)
matrix.fillRect(1 + (4 - x) * 6, 1 + y * 6, 5 + (4 - x) * 6, 5 + y * 6, color);
}
}
effects.ShowFrame();
return 2000;
}
};
#endif

View file

@ -0,0 +1,129 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from Andrew: http://pastebin.com/f22bfe94d
* which, in turn, was "Adapted from the Life example on the Processing.org site"
*
* Made much more colorful by J.B. Langston: https://github.com/jblang/aurora/commit/6db5a884e3df5d686445c4f6b669f1668841929b
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternLife_H
#define PatternLife_H
class Cell {
public:
byte alive : 1;
byte prev : 1;
byte hue: 6;
byte brightness;
};
class PatternLife : public Drawable {
private:
Cell world[MATRIX_WIDTH][MATRIX_HEIGHT];
unsigned int density = 50;
int generation = 0;
void randomFillWorld() {
for (int i = 0; i < MATRIX_WIDTH; i++) {
for (int j = 0; j < MATRIX_HEIGHT; j++) {
if (random(100) < density) {
world[i][j].alive = 1;
world[i][j].brightness = 255;
}
else {
world[i][j].alive = 0;
world[i][j].brightness = 0;
}
world[i][j].prev = world[i][j].alive;
world[i][j].hue = 0;
}
}
}
int neighbours(int x, int y) {
return (world[(x + 1) % MATRIX_WIDTH][y].prev) +
(world[x][(y + 1) % MATRIX_HEIGHT].prev) +
(world[(x + MATRIX_WIDTH - 1) % MATRIX_WIDTH][y].prev) +
(world[x][(y + MATRIX_HEIGHT - 1) % MATRIX_HEIGHT].prev) +
(world[(x + 1) % MATRIX_WIDTH][(y + 1) % MATRIX_HEIGHT].prev) +
(world[(x + MATRIX_WIDTH - 1) % MATRIX_WIDTH][(y + 1) % MATRIX_HEIGHT].prev) +
(world[(x + MATRIX_WIDTH - 1) % MATRIX_WIDTH][(y + MATRIX_HEIGHT - 1) % MATRIX_HEIGHT].prev) +
(world[(x + 1) % MATRIX_WIDTH][(y + MATRIX_HEIGHT - 1) % MATRIX_HEIGHT].prev);
}
public:
PatternLife() {
name = (char *)"Life";
}
unsigned int drawFrame() {
if (generation == 0) {
effects.ClearFrame();
randomFillWorld();
}
// Display current generation
for (int i = 0; i < MATRIX_WIDTH; i++) {
for (int j = 0; j < MATRIX_HEIGHT; j++) {
effects.leds[XY(i, j)] = effects.ColorFromCurrentPalette(world[i][j].hue * 4, world[i][j].brightness);
}
}
// Birth and death cycle
for (int x = 0; x < MATRIX_WIDTH; x++) {
for (int y = 0; y < MATRIX_HEIGHT; y++) {
// Default is for cell to stay the same
if (world[x][y].brightness > 0 && world[x][y].prev == 0)
world[x][y].brightness *= 0.9;
int count = neighbours(x, y);
if (count == 3 && world[x][y].prev == 0) {
// A new cell is born
world[x][y].alive = 1;
world[x][y].hue += 2;
world[x][y].brightness = 255;
} else if ((count < 2 || count > 3) && world[x][y].prev == 1) {
// Cell dies
world[x][y].alive = 0;
}
}
}
// Copy next generation into place
for (int x = 0; x < MATRIX_WIDTH; x++) {
for (int y = 0; y < MATRIX_HEIGHT; y++) {
world[x][y].prev = world[x][y].alive;
}
}
generation++;
if (generation >= 256)
generation = 0;
effects.ShowFrame();
return 60;
}
};
#endif

View file

@ -0,0 +1,264 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Many thanks to Jamis Buck for the documentation of the Growing Tree maze generation algorithm: http://weblog.jamisbuck.org/2011/1/27/maze-generation-growing-tree-algorithm
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternMaze_H
#define PatternMaze_H
class PatternMaze : public Drawable {
private:
enum Directions {
None = 0,
Up = 1,
Down = 2,
Left = 4,
Right = 8,
};
struct Point{
int x;
int y;
static Point New(int x, int y) {
Point point;
point.x = x;
point.y = y;
return point;
}
Point Move(Directions direction) {
switch (direction)
{
case Up:
return New(x, y - 1);
case Down:
return New(x, y + 1);
case Left:
return New(x - 1, y);
case Right:
default:
return New(x + 1, y);
}
}
static Directions Opposite(Directions direction) {
switch (direction) {
case Up:
return Down;
case Down:
return Up;
case Left:
return Right;
case Right:
default:
return Left;
}
}
};
// int width = 16;
// int height = 16;
static const int width = MATRIX_WIDTH / 2;
static const int height = MATRIX_HEIGHT / 2;
Directions grid[width][height];
Point point;
Point cells[256];
int cellCount = 0;
int algorithm = 0;
int algorithmCount = 1;
byte hue = 0;
byte hueOffset = 0;
Directions directions[4] = { Up, Down, Left, Right };
void removeCell(int index) {// shift cells after index down one
for (int i = index; i < cellCount - 1; i++) {
cells[i] = cells[i + 1];
}
cellCount--;
}
void shuffleDirections() {
for (int a = 0; a < 4; a++)
{
int r = random(a, 4);
Directions temp = directions[a];
directions[a] = directions[r];
directions[r] = temp;
}
}
Point createPoint(int x, int y) {
Point point;
point.x = x;
point.y = y;
return point;
}
CRGB chooseColor(int index) {
byte h = index + hueOffset;
switch (algorithm) {
case 0:
default:
return effects.ColorFromCurrentPalette(h);
case 1:
return effects.ColorFromCurrentPalette(hue++);
}
}
int chooseIndex(int max) {
switch (algorithm) {
case 0:
default:
// choose newest (recursive backtracker)
return max - 1;
case 1:
// choose random(Prim's)
return random(max);
// case 2:
// // choose oldest (not good, so disabling)
// return 0;
}
}
void generateMaze() {
while (cellCount > 1) {
drawNextCell();
}
}
void drawNextCell() {
int index = chooseIndex(cellCount);
if (index < 0)
return;
point = cells[index];
Point imagePoint = createPoint(point.x * 2, point.y * 2);
//effects.drawBackgroundFastLEDPixelCRGB(imagePoint.x, imagePoint.y, CRGB(CRGB::Gray));
shuffleDirections();
CRGB color = chooseColor(index);
for (int i = 0; i < 4; i++) {
Directions direction = directions[i];
Point newPoint = point.Move(direction);
if (newPoint.x >= 0 && newPoint.y >= 0 && newPoint.x < width && newPoint.y < height && grid[newPoint.y][newPoint.x] == None) {
grid[point.y][point.x] = (Directions) ((int) grid[point.y][point.x] | (int) direction);
grid[newPoint.y][newPoint.x] = (Directions) ((int) grid[newPoint.y][newPoint.x] | (int) point.Opposite(direction));
Point newImagePoint = imagePoint.Move(direction);
effects.drawBackgroundFastLEDPixelCRGB(newImagePoint.x, newImagePoint.y, color);
cellCount++;
cells[cellCount - 1] = newPoint;
index = -1;
break;
}
}
if (index > -1) {
Point finishedPoint = cells[index];
imagePoint = createPoint(finishedPoint.x * 2, finishedPoint.y * 2);
effects.drawBackgroundFastLEDPixelCRGB(imagePoint.x, imagePoint.y, color);
removeCell(index);
}
}
public:
PatternMaze() {
name = (char *)"Maze";
}
unsigned int drawFrame() {
if (cellCount < 1) {
effects.ClearFrame();
// reset the maze grid
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
grid[y][x] = None;
}
}
int x = random(width);
int y = random(height);
cells[0] = createPoint(x, y);
cellCount = 1;
hue = 0;
hueOffset = random(0, 256);
}
drawNextCell();
if (cellCount < 1) {
algorithm++;
if (algorithm >= algorithmCount)
algorithm = 0;
return 1000;
}
effects.ShowFrame();
return 0;
}
void start() {
matrix.fillScreen(0);
cellCount = 0;
hue = 0;
}
};
#endif

View file

@ -0,0 +1,74 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Munch pattern created by J.B. Langston: https://github.com/jblang/aurora/blob/master/PatternMunch.h
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternMunch_H
#define PatternMunch_H
class PatternMunch : public Drawable {
private:
byte count = 0;
byte dir = 1;
byte flip = 0;
byte generation = 0;
public:
PatternMunch() {
name = (char *)"Munch";
}
unsigned int drawFrame() {
for (byte x = 0; x < MATRIX_WIDTH; x++) {
for (byte y = 0; y < MATRIX_HEIGHT; y++) {
effects.leds[XY(x, y)] = (x ^ y ^ flip) < count ? effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) : CRGB::Black;
// The below is more pleasant
// effects.leds[XY(x, y)] = effects.ColorFromCurrentPalette(((x ^ y) << 2) + generation) ;
}
}
count += dir;
if (count <= 0 || count >= MATRIX_WIDTH) {
dir = -dir;
}
if (count <= 0) {
if (flip == 0)
flip = MATRIX_WIDTH-1;
else
flip = 0;
}
generation++;
// show it ffs!
effects.ShowFrame();
return 60;
}
};
#endif

View file

@ -0,0 +1,338 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from "Noise Smearing" by Stefan Petrick: https://gist.githubusercontent.com/embedded-creations/5cd47d83cb0e04f4574d/raw/ebf6a82b4755d55cfba3bf6598f7b19047f89daf/NoiseSmearing.ino
* Copyright (c) 2014 Stefan Petrick
* http://www.stefan-petrick.de/wordpress_beta
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternNoiseSmearing_H
#define PatternNoiseSmearing_H
byte patternNoiseSmearingHue = 0;
class PatternMultipleStream : public Drawable {
public:
PatternMultipleStream() {
name = (char *)"MultipleStream";
}
// this pattern draws two points to the screen based on sin/cos if a counter
// (comment out NoiseSmearWithRadius to see pattern of pixels)
// these pixels are smeared by a large radius, giving a lot of movement
// the image is dimmed before each drawing to not saturate the screen with color
// the smear has an offset so the pixels usually have a trail leading toward the upper left
unsigned int drawFrame() {
static unsigned long counter = 0;
#if 0
// this counter lets put delays between each frame and still get the same animation
counter++;
#else
// this counter updates in real time and can't be slowed down for debugging
counter = millis() / 10;
#endif
byte x1 = 4 + sin8(counter * 2) / 10;
byte x2 = 8 + sin8(counter * 2) / 16;
byte y2 = 8 + cos8((counter * 2) / 3) / 16;
effects.leds[XY(x1, x2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue);
effects.leds[XY(x2, y2)] = effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 128);
// Noise
noise_x += 1000;
noise_y += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(8);
effects.MoveFractionalNoiseX();
effects.MoveY(8);
effects.MoveFractionalNoiseY();
patternNoiseSmearingHue++;
return 0;
}
};
class PatternMultipleStream2 : public Drawable {
public:
PatternMultipleStream2() {
name = (char *)"MultipleStream2";
}
unsigned int drawFrame() {
effects.DimAll(230); effects.ShowFrame();
byte xx = 4 + sin8(millis() / 9) / 10;
byte yy = 4 + cos8(millis() / 10) / 10;
effects.leds[XY(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue);
xx = 8 + sin8(millis() / 10) / 16;
yy = 8 + cos8(millis() / 7) / 16;
effects.leds[XY(xx, yy)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 80);
effects.leds[XY(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue + 160);
noise_x += 1000;
noise_y += 1000;
noise_z += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(3);
effects.MoveFractionalNoiseY(4);
effects.MoveY(3);
effects.MoveFractionalNoiseX(4);
patternNoiseSmearingHue++;
return 0;
}
};
class PatternMultipleStream3 : public Drawable {
public:
PatternMultipleStream3() {
name = (char *)"MultipleStream3";
}
unsigned int drawFrame() {
//CLS();
effects.DimAll(235); effects.ShowFrame();
for (uint8_t i = 3; i < 32; i = i + 4) {
effects.leds[XY(i, 15)] += effects.ColorFromCurrentPalette(i * 8);
}
// Noise
noise_x += 1000;
noise_y += 1000;
noise_z += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(3);
effects.MoveFractionalNoiseY(4);
effects.MoveY(3);
effects.MoveFractionalNoiseX(4);
effects.ShowFrame();
return 1;
}
};
class PatternMultipleStream4 : public Drawable {
public:
PatternMultipleStream4() {
name = (char *)"MultipleStream4";
}
unsigned int drawFrame() {
//CLS();
effects.DimAll(235); effects.ShowFrame();
effects.leds[XY(15, 15)] += effects.ColorFromCurrentPalette(patternNoiseSmearingHue);
// Noise
noise_x += 1000;
noise_y += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(8);
effects.MoveFractionalNoiseX();
effects.MoveY(8);
effects.MoveFractionalNoiseY();
patternNoiseSmearingHue++;
return 0;
}
};
class PatternMultipleStream5 : public Drawable {
public:
PatternMultipleStream5() {
name = (char *)"MultipleStream5";
}
unsigned int drawFrame() {
//CLS();
effects.DimAll(235); effects.ShowFrame();
for (uint8_t i = 3; i < 32; i = i + 4) {
effects.leds[XY(i, 31)] += effects.ColorFromCurrentPalette(i * 8);
}
// Noise
noise_x += 1000;
noise_y += 1000;
noise_z += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(3);
effects.MoveFractionalNoiseY(4);
effects.MoveY(4);
effects.MoveFractionalNoiseX(4);
return 0;
}
};
class PatternMultipleStream8 : public Drawable {
public:
PatternMultipleStream8() {
name = (char *)"MultipleStream8";
}
unsigned int drawFrame() {
effects.DimAll(230); effects.ShowFrame();
// draw grid of rainbow dots on top of the dimmed image
for (uint8_t y = 1; y < 32; y = y + 6) {
for (uint8_t x = 1; x < 32; x = x + 6) {
effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette((x * y) / 4);
}
}
// Noise
noise_x += 1000;
noise_y += 1000;
noise_z += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(3);
effects.MoveFractionalNoiseX(4);
effects.MoveY(3);
effects.MoveFractionalNoiseY(4);
return 0;
}
};
class PatternPaletteSmear : public Drawable {
public:
PatternPaletteSmear() {
name = (char *)"PaletteSmear";
}
unsigned int drawFrame() {
effects.DimAll(170); effects.ShowFrame();
// draw a rainbow color palette
for (uint8_t y = 0; y < MATRIX_HEIGHT; y++) {
for (uint8_t x = 0; x < MATRIX_WIDTH; x++) {
effects.leds[XY(x, y)] += effects.ColorFromCurrentPalette(x * 8, y * 8 + 7);
}
}
// Noise
noise_x += 1000;
noise_y += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(3);
//effects.MoveFractionalNoiseY(4);
effects.MoveY(3);
effects.MoveFractionalNoiseX(4);
effects.ShowFrame();
return 0;
}
};
class PatternRainbowFlag : public Drawable {
public:
PatternRainbowFlag() {
name = (char *)"RainbowFlag";
}
unsigned int drawFrame() {
effects.DimAll(10); effects.ShowFrame();
CRGB rainbow[7] = {
CRGB::Red,
CRGB::Orange,
CRGB::Yellow,
CRGB::Green,
CRGB::Blue,
CRGB::Violet
};
uint8_t y = 2;
for (uint8_t c = 0; c < 6; c++) {
for (uint8_t j = 0; j < 5; j++) {
for (uint8_t x = 0; x < MATRIX_WIDTH; x++) {
effects.leds[XY(x, y)] += rainbow[c];
}
y++;
if (y >= MATRIX_HEIGHT)
break;
}
}
// Noise
noise_x += 1000;
noise_y += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(3);
effects.MoveFractionalNoiseY(4);
effects.MoveY(3);
effects.MoveFractionalNoiseX(4);
return 0;
}
};
#endif

View file

@ -0,0 +1,56 @@
/*
*
* Inspired by and based on a loading animation for Prismata by Lunarch Studios:
* http://www.reddit.com/r/gifs/comments/2on8si/connecting_to_server_so_mesmerizing/cmow0sz
*
* Lunarch Studios Inc. hereby publishes the Actionscript 3 source code pasted in this
* comment under the Creative Commons CC0 1.0 Universal Public Domain Dedication.
* Lunarch Studios Inc. waives all rights to the work worldwide under copyright law,
* including all related and neighboring rights, to the extent allowed by law.
* You can copy, modify, distribute and perform the work, even for commercial purposes,
* all without asking permission.
*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternPendulumWave_H
#define PatternPendulumWave_H
class PatternPendulumWave : public Drawable {
public:
PatternPendulumWave() {
name = (char *)"Pendulum Wave";
}
unsigned int drawFrame() {
effects.DimAll(170); effects.ShowFrame();
for (int x = 0; x < MATRIX_WIDTH; x++)
{
uint8_t y = beatsin8(x + MATRIX_WIDTH, 0, MATRIX_HEIGHT);
effects.drawBackgroundFastLEDPixelCRGB(x, y, effects.ColorFromCurrentPalette(x * 7));
}
return 15;
}
};
#endif

View file

@ -0,0 +1,66 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from LedEffects Plasma by Robert Atkins: https://bitbucket.org/ratkins/ledeffects/src/26ed3c51912af6fac5f1304629c7b4ab7ac8ca4b/Plasma.cpp?at=default
* Copyright (c) 2013 Robert Atkins
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternPlasma_H
#define PatternPlasma_H
class PatternPlasma : public Drawable {
private:
int time = 0;
int cycles = 0;
public:
PatternPlasma() {
name = (char *)"Plasma";
}
unsigned int drawFrame() {
for (int x = 0; x < MATRIX_WIDTH; x++) {
for (int y = 0; y < MATRIX_HEIGHT; y++) {
int16_t v = 0;
uint8_t wibble = sin8(time);
v += sin16(x * wibble * 2 + time);
v += cos16(y * (128 - wibble) * 2 + time);
v += sin16(y * x * cos8(-time) / 2);
effects.Pixel(x, y, (v >> 8) + 127);
}
}
time += 1;
cycles++;
if (cycles >= 2048) {
time = 0;
cycles = 0;
}
effects.ShowFrame();
return 30;
}
};
#endif

View file

@ -0,0 +1,82 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Based at least in part on someone else's work that I can no longer find.
* Please let me know if you recognize any of this code!
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternPulse_H
#define PatternPulse_H
class PatternPulse : public Drawable {
private:
int hue;
int centerX = 0;
int centerY = 0;
int step = -1;
int maxSteps = 16;
float fadeRate = 0.8;
int diff;
public:
PatternPulse() {
name = (char *)"Pulse";
}
unsigned int drawFrame() {
effects.DimAll(235);
if (step == -1) {
centerX = random(32);
centerY = random(32);
hue = random(256); // 170;
step = 0;
}
if (step == 0) {
matrix.drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue));
step++;
}
else {
if (step < maxSteps) {
// initial pulse
matrix.drawCircle(centerX, centerY, step, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255));
// secondary pulse
if (step > 3) {
matrix.drawCircle(centerX, centerY, step - 3, effects.ColorFromCurrentPalette(hue, pow(fadeRate, step - 2) * 255));
}
step++;
}
else {
step = -1;
}
}
effects.standardNoiseSmearing();
effects.ShowFrame();
return 30;
}
};
#endif

View file

@ -0,0 +1,56 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternRadar_H
class PatternRadar : public Drawable {
private:
byte theta = 0;
byte hueoffset = 0;
public:
PatternRadar() {
name = (char *)"Radar";
}
unsigned int drawFrame() {
effects.DimAll(254); effects.ShowFrame();
for (int offset = 0; offset < MATRIX_CENTER_X; offset++) {
byte hue = 255 - (offset * 16 + hueoffset);
CRGB color = effects.ColorFromCurrentPalette(hue);
uint8_t x = mapcos8(theta, offset, (MATRIX_WIDTH - 1) - offset);
uint8_t y = mapsin8(theta, offset, (MATRIX_HEIGHT - 1) - offset);
uint16_t xy = XY(x, y);
effects.leds[xy] = color;
EVERY_N_MILLIS(25) {
theta += 2;
hueoffset += 1;
}
}
return 0;
}
};
#endif

View file

@ -0,0 +1,79 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/blob/master/examples/Noise/Noise.ino
* Copyright (c) 2013 FastLED
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternSimplexNoise_H
#define PatternSimplexNoise_H
class PatternSimplexNoise : public Drawable {
public:
PatternSimplexNoise() {
name = (char *)"Noise";
}
void start() {
// Initialize our coordinates to some random values
noise_x = random16();
noise_y = random16();
noise_z = random16();
}
unsigned int drawFrame() {
#if FASTLED_VERSION >= 3001000
// a new parameter set every 15 seconds
EVERY_N_SECONDS(15) {
noise_x = random16();
noise_y = random16();
noise_z = random16();
}
#endif
uint32_t speed = 100;
effects.FillNoise();
ShowNoiseLayer(0, 1, 0);
// noise_x += speed;
noise_y += speed;
noise_z += speed;
effects.ShowFrame();
return 0;
}
// show just one layer
void ShowNoiseLayer(byte layer, byte colorrepeat, byte colorshift) {
for (uint8_t i = 0; i < MATRIX_WIDTH; i++) {
for (uint8_t j = 0; j < MATRIX_HEIGHT; j++) {
uint8_t pixel = noise[i][j];
// assign a color depending on the actual palette
effects.leds[XY(i, j)] = effects.ColorFromCurrentPalette(colorrepeat * (pixel + colorshift), pixel);
}
}
}
};
#endif

View file

@ -0,0 +1,145 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from LedEffects Snake by Robert Atkins: https://bitbucket.org/ratkins/ledeffects/src/26ed3c51912af6fac5f1304629c7b4ab7ac8ca4b/Snake.cpp?at=default
* Copyright (c) 2013 Robert Atkins
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternSnake_H
#define PatternSnake_H
class PatternSnake : public Drawable {
private:
static const byte SNAKE_LENGTH = 16;
CRGB colors[SNAKE_LENGTH];
uint8_t initialHue;
enum Direction {
UP, DOWN, LEFT, RIGHT
};
struct Pixel {
uint8_t x;
uint8_t y;
};
struct Snake {
Pixel pixels[SNAKE_LENGTH];
Direction direction;
void newDirection() {
switch (direction) {
case UP:
case DOWN:
direction = random(0, 2) == 1 ? RIGHT : LEFT;
break;
case LEFT:
case RIGHT:
direction = random(0, 2) == 1 ? DOWN : UP;
default:
break;
}
}
void shuffleDown() {
for (byte i = SNAKE_LENGTH - 1; i > 0; i--) {
pixels[i] = pixels[i - 1];
}
}
void reset() {
direction = UP;
for (int i = 0; i < SNAKE_LENGTH; i++) {
pixels[i].x = 0;
pixels[i].y = 0;
}
}
void move() {
switch (direction) {
case UP:
pixels[0].y = (pixels[0].y + 1) % MATRIX_HEIGHT;
break;
case LEFT:
pixels[0].x = (pixels[0].x + 1) % MATRIX_WIDTH;
break;
case DOWN:
pixels[0].y = pixels[0].y == 0 ? MATRIX_HEIGHT - 1 : pixels[0].y - 1;
break;
case RIGHT:
pixels[0].x = pixels[0].x == 0 ? MATRIX_WIDTH - 1 : pixels[0].x - 1;
break;
}
}
void draw(CRGB colors[SNAKE_LENGTH]) {
for (byte i = 0; i < SNAKE_LENGTH; i++) {
effects.leds[XY(pixels[i].x, pixels[i].y)] = colors[i] %= (255 - i * (255 / SNAKE_LENGTH));
}
}
};
static const int snakeCount = 6;
Snake snakes[snakeCount];
public:
PatternSnake() {
name = (char *)"Snake";
for (int i = 0; i < snakeCount; i++) {
Snake* snake = &snakes[i];
snake->reset();
}
}
void start()
{
effects.ClearFrame();
}
unsigned int drawFrame() {
fill_palette(colors, SNAKE_LENGTH, initialHue++, 5, effects.currentPalette, 255, LINEARBLEND);
for (int i = 0; i < snakeCount; i++) {
Snake* snake = &snakes[i];
snake->shuffleDown();
if (random(10) > 7) {
snake->newDirection();
}
snake->move();
snake->draw(colors);
}
effects.ShowFrame();
return 30;
}
};
#endif

View file

@ -0,0 +1,113 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from FastLED Fire2012 example by Mark Kriegsman: https://github.com/FastLED/FastLED/tree/master/examples/Fire2012WithPalette
* Copyright (c) 2013 FastLED
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternSpark_H
#define PatternSpark_H
class PatternSpark : public Drawable {
private:
public:
PatternSpark() {
name = (char *)"Spark";
}
// There are two main parameters you can play with to control the look and
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
// in step 3 above).
//
// COOLING: How much does the air cool as it rises?
// Less cooling = taller flames. More cooling = shorter flames.
// Default 55, suggested range 20-100
uint8_t cooling = 100;
// SPARKING: What chance (out of 255) is there that a new spark will be lit?
// Higher chance = more roaring fire. Lower chance = more flickery fire.
// Default 120, suggested range 50-200.
uint8_t sparking = 50;
unsigned int drawFrame() {
// Add entropy to random number generator; we use a lot of it.
random16_add_entropy( random16());
effects.DimAll(235); effects.ShowFrame();
for (uint8_t x = 0; x < MATRIX_WIDTH; x++) {
// Step 1. Cool down every cell a little
for (int y = 0; y < MATRIX_HEIGHT; y++) {
int xy = XY(x, y);
heat[xy] = qsub8(heat[xy], random8(0, ((cooling * 10) / MATRIX_HEIGHT) + 2));
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for (int y = 0; y < MATRIX_HEIGHT; y++) {
heat[XY(x, y)] = (heat[XY(x, y + 1)] + heat[XY(x, y + 2)] + heat[XY(x, y + 2)]) / 3;
}
// Step 2. Randomly ignite new 'sparks' of heat
if (random8() < sparking) {
uint8_t xt = random8(MATRIX_CENTRE_X - 2, MATRIX_CENTER_X + 3);
int xy = XY(xt, MATRIX_HEIGHT - 1);
heat[xy] = qadd8(heat[xy], random8(160, 255));
}
// Step 4. Map from heat cells to LED colors
for (int y = 0; y < MATRIX_HEIGHT; y++) {
int xy = XY(x, y);
byte colorIndex = heat[xy];
// Recommend that you use values 0-240 rather than
// the usual 0-255, as the last 15 colors will be
// 'wrapping around' from the hot end to the cold end,
// which looks wrong.
colorIndex = scale8(colorIndex, 240);
// override color 0 to ensure a black background?
if (colorIndex != 0)
// effects.leds[xy] = CRGB::Black;
// else
effects.leds[xy] = effects.ColorFromCurrentPalette(colorIndex);
}
}
// Noise
noise_x += 1000;
noise_y += 1000;
noise_z += 1000;
noise_scale_x = 4000;
noise_scale_y = 4000;
effects.FillNoise();
effects.MoveX(3);
effects.MoveFractionalNoiseX(4);
effects.ShowFrame();
return 15;
}
};
#endif

View file

@ -0,0 +1,100 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternSpin_H
class PatternSpin : public Drawable {
public:
PatternSpin() {
name = (char *)"Spin";
}
float degrees = 0;
float radius = 16;
float speedStart = 1;
float velocityStart = 0.6;
float maxSpeed = 30;
float speed = speedStart;
float velocity = velocityStart;
void start() {
speed = speedStart;
velocity = velocityStart;
degrees = 0;
}
unsigned int drawFrame() {
effects.DimAll(190); effects.ShowFrame();
CRGB color = effects.ColorFromCurrentPalette(speed * 8);
// start position
int x;
int y;
// target position
float targetDegrees = degrees + speed;
float targetRadians = radians(targetDegrees);
int targetX = (int) (MATRIX_CENTER_X + radius * cos(targetRadians));
int targetY = (int) (MATRIX_CENTER_Y - radius * sin(targetRadians));
float tempDegrees = degrees;
do{
float radians = radians(tempDegrees);
x = (int) (MATRIX_CENTER_X + radius * cos(radians));
y = (int) (MATRIX_CENTER_Y - radius * sin(radians));
effects.drawBackgroundFastLEDPixelCRGB(x, y, color);
effects.drawBackgroundFastLEDPixelCRGB(y, x, color);
tempDegrees += 1;
if (tempDegrees >= 360)
tempDegrees = 0;
} while (x != targetX || y != targetY);
degrees += speed;
// add velocity to the particle each pass around the accelerator
if (degrees >= 360) {
degrees = 0;
speed += velocity;
if (speed <= speedStart) {
speed = speedStart;
velocity *= -1;
}
else if (speed > maxSpeed){
speed = maxSpeed - velocity;
velocity *= -1;
}
}
return 0;
}
};
#endif

View file

@ -0,0 +1,138 @@
/*
* Portions of this code are adapted from "Funky Clouds" by Stefan Petrick:
* https://gist.github.com/anonymous/876f908333cd95315c35
*
* Copyright (c) 2014 Stefan Petrick
* http://www.stefan-petrick.de/wordpress_beta
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternSpiral_H
#define PatternSpiral_H
class PatternSpiral : public Drawable {
private:
// Timer stuff (Oszillators)
struct timer {
unsigned long takt;
unsigned long lastMillis;
unsigned long count;
int delta;
byte up;
byte down;
};
timer multiTimer[5];
int timers = sizeof(multiTimer) / sizeof(multiTimer[0]);
// counts all variables with different speeds linear up and down
void UpdateTimers()
{
unsigned long now = millis();
for (int i = 0; i < timers; i++)
{
while (now - multiTimer[i].lastMillis >= multiTimer[i].takt)
{
multiTimer[i].lastMillis += multiTimer[i].takt;
multiTimer[i].count = multiTimer[i].count + multiTimer[i].delta;
if ((multiTimer[i].count == multiTimer[i].up) || (multiTimer[i].count == multiTimer[i].down))
{
multiTimer[i].delta = -multiTimer[i].delta;
}
}
}
}
public:
PatternSpiral() {
name = (char *)"Spiral";
}
void start() {
// set all counting directions positive for the beginning
for (int i = 0; i < timers; i++) multiTimer[i].delta = 1;
// set range (up/down), speed (takt=ms between steps) and starting point of all oszillators
unsigned long now = millis();
multiTimer[0].lastMillis = now;
multiTimer[0].takt = 42; //x1
multiTimer[0].up = MATRIX_WIDTH - 1;
multiTimer[0].down = 0;
multiTimer[0].count = 0;
multiTimer[1].lastMillis = now;
multiTimer[1].takt = 55; //y1
multiTimer[1].up = MATRIX_HEIGHT - 1;
multiTimer[1].down = 0;
multiTimer[1].count = 0;
multiTimer[2].lastMillis = now;
multiTimer[2].takt = 3; //color
multiTimer[2].up = 255;
multiTimer[2].down = 0;
multiTimer[2].count = 0;
multiTimer[3].lastMillis = now;
multiTimer[3].takt = 71; //x2
multiTimer[3].up = MATRIX_WIDTH - 1;
multiTimer[3].down = 0;
multiTimer[3].count = 0;
multiTimer[4].lastMillis = now;
multiTimer[4].takt = 89; //y2
multiTimer[4].up = MATRIX_HEIGHT - 1;
multiTimer[4].down = 0;
multiTimer[4].count = 0;
}
unsigned int drawFrame() {
// manage the Oszillators
UpdateTimers();
// draw just a line defined by 5 oszillators
effects.BresenhamLine(
multiTimer[3].count, // x1
multiTimer[4].count, // y1
multiTimer[0].count, // x2
multiTimer[1].count, // y2
multiTimer[2].count); // color
// manipulate the screen buffer
// with fixed parameters (could be oszillators too)
// Params: center x, y, radius, scale color down
// --> NOTE: Affects always a SQUARE with an odd length
// effects.SpiralStream(15, 15, 10, 128);
effects.SpiralStream(31, 15, 64, 128); // for 64 pixel wide matrix!
// effects.SpiralStream(47, 15, 10, 128); // for 64 pixel wide matrix!
// why not several times?!
// effects.SpiralStream(16, 6, 6, 128);
// effects.SpiralStream(10, 24, 10, 128);
// increase the contrast
effects.DimAll(250); effects.ShowFrame();
return 0;
}
};
#endif

View file

@ -0,0 +1,107 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternSpiro_H
class PatternSpiro : public Drawable {
private:
byte theta1 = 0;
byte theta2 = 0;
byte hueoffset = 0;
uint8_t radiusx = MATRIX_WIDTH / 4;
uint8_t radiusy = MATRIX_HEIGHT / 4;
uint8_t minx = MATRIX_CENTER_X - radiusx;
uint8_t maxx = MATRIX_CENTER_X + radiusx + 1;
uint8_t miny = MATRIX_CENTER_Y - radiusy;
uint8_t maxy = MATRIX_CENTER_Y + radiusy + 1;
uint8_t spirocount = 1;
uint8_t spirooffset = 256 / spirocount;
boolean spiroincrement = false;
boolean handledChange = false;
public:
PatternSpiro() {
name = (char *)"Spiro";
}
unsigned int drawFrame() {
effects.DimAll(254); effects.ShowFrame();
boolean change = false;
for (int i = 0; i < spirocount; i++) {
uint8_t x = mapsin8(theta1 + i * spirooffset, minx, maxx);
uint8_t y = mapcos8(theta1 + i * spirooffset, miny, maxy);
uint8_t x2 = mapsin8(theta2 + i * spirooffset, x - radiusx, x + radiusx);
uint8_t y2 = mapcos8(theta2 + i * spirooffset, y - radiusy, y + radiusy);
CRGB color = effects.ColorFromCurrentPalette(hueoffset + i * spirooffset, 128);
effects.leds[XY(x2, y2)] += color;
if((x2 == MATRIX_CENTER_X && y2 == MATRIX_CENTER_Y) ||
(x2 == MATRIX_CENTRE_X && y2 == MATRIX_CENTRE_Y)) change = true;
}
theta2 += 1;
EVERY_N_MILLIS(25) {
theta1 += 1;
}
EVERY_N_MILLIS(100) {
if (change && !handledChange) {
handledChange = true;
if (spirocount >= MATRIX_WIDTH || spirocount == 1) spiroincrement = !spiroincrement;
if (spiroincrement) {
if(spirocount >= 4)
spirocount *= 2;
else
spirocount += 1;
}
else {
if(spirocount > 4)
spirocount /= 2;
else
spirocount -= 1;
}
spirooffset = 256 / spirocount;
}
if(!change) handledChange = false;
}
EVERY_N_MILLIS(33) {
hueoffset += 1;
}
return 0;
}
};
#endif

View file

@ -0,0 +1,77 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Portions of this code are adapted from SmartMatrixSwirl by Mark Kriegsman: https://gist.github.com/kriegsman/5adca44e14ad025e6d3b
* https://www.youtube.com/watch?v=bsGBT-50cts
* Copyright (c) 2014 Mark Kriegsman
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternSwirl_H
class PatternSwirl : public Drawable {
private:
const uint8_t borderWidth = 2;
public:
PatternSwirl() {
name = (char *)"Swirl";
}
void start() {
}
unsigned int drawFrame() {
// Apply some blurring to whatever's already on the matrix
// Note that we never actually clear the matrix, we just constantly
// blur it repeatedly. Since the blurring is 'lossy', there's
// an automatic trend toward black -- by design.
uint8_t blurAmount = beatsin8(2, 10, 255);
#if FASTLED_VERSION >= 3001000
blur2d(effects.leds, MATRIX_WIDTH, MATRIX_HEIGHT, blurAmount);
#else
effects.DimAll(blurAmount);
#endif
// Use two out-of-sync sine waves
uint8_t i = beatsin8(27, borderWidth, MATRIX_HEIGHT - borderWidth);
uint8_t j = beatsin8(41, borderWidth, MATRIX_WIDTH - borderWidth);
// Also calculate some reflections
uint8_t ni = (MATRIX_WIDTH - 1) - i;
uint8_t nj = (MATRIX_WIDTH - 1) - j;
// The color of each point shifts over time, each at a different speed.
uint16_t ms = millis();
effects.leds[XY(i, j)] += effects.ColorFromCurrentPalette(ms / 11);
effects.leds[XY(j, i)] += effects.ColorFromCurrentPalette(ms / 13);
effects.leds[XY(ni, nj)] += effects.ColorFromCurrentPalette(ms / 17);
effects.leds[XY(nj, ni)] += effects.ColorFromCurrentPalette(ms / 29);
effects.leds[XY(i, nj)] += effects.ColorFromCurrentPalette(ms / 37);
effects.leds[XY(ni, j)] += effects.ColorFromCurrentPalette(ms / 41);
effects.ShowFrame();
return 0;
}
};
#endif

View file

@ -0,0 +1,20 @@
#ifndef PatternTest_H
#define PatternTest_H
class PatternTest : public Drawable {
private:
public:
PatternTest() {
name = (char *)"Test Pattern";
}
unsigned int drawFrame() {
matrix.fillScreen(matrix.color565(128, 0, 0));
}
};
#endif

View file

@ -0,0 +1,120 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef PatternWave_H
#define PatternWave_H
class PatternWave : public Drawable {
private:
byte thetaUpdate = 0;
byte thetaUpdateFrequency = 0;
byte theta = 0;
byte hueUpdate = 0;
byte hueUpdateFrequency = 0;
byte hue = 0;
byte rotation = 0;
uint8_t scale = 256 / MATRIX_WIDTH;
uint8_t maxX = MATRIX_WIDTH - 1;
uint8_t maxY = MATRIX_HEIGHT - 1;
uint8_t waveCount = 1;
public:
PatternWave() {
name = (char *)"Wave";
}
void start() {
rotation = random(0, 4);
waveCount = random(1, 3);
}
unsigned int drawFrame() {
int n = 0;
switch (rotation) {
case 0:
for (int x = 0; x < MATRIX_WIDTH; x++) {
n = quadwave8(x * 2 + theta) / scale;
effects.drawBackgroundFastLEDPixelCRGB(x, n, effects.ColorFromCurrentPalette(x + hue));
if (waveCount == 2)
effects.drawBackgroundFastLEDPixelCRGB(x, maxY - n, effects.ColorFromCurrentPalette(x + hue));
}
break;
case 1:
for (int y = 0; y < MATRIX_HEIGHT; y++) {
n = quadwave8(y * 2 + theta) / scale;
effects.drawBackgroundFastLEDPixelCRGB(n, y, effects.ColorFromCurrentPalette(y + hue));
if (waveCount == 2)
effects.drawBackgroundFastLEDPixelCRGB(maxX - n, y, effects.ColorFromCurrentPalette(y + hue));
}
break;
case 2:
for (int x = 0; x < MATRIX_WIDTH; x++) {
n = quadwave8(x * 2 - theta) / scale;
effects.drawBackgroundFastLEDPixelCRGB(x, n, effects.ColorFromCurrentPalette(x + hue));
if (waveCount == 2)
effects.drawBackgroundFastLEDPixelCRGB(x, maxY - n, effects.ColorFromCurrentPalette(x + hue));
}
break;
case 3:
for (int y = 0; y < MATRIX_HEIGHT; y++) {
n = quadwave8(y * 2 - theta) / scale;
effects.drawBackgroundFastLEDPixelCRGB(n, y, effects.ColorFromCurrentPalette(y + hue));
if (waveCount == 2)
effects.drawBackgroundFastLEDPixelCRGB(maxX - n, y, effects.ColorFromCurrentPalette(y + hue));
}
break;
}
effects.DimAll(254);
effects.ShowFrame();
if (thetaUpdate >= thetaUpdateFrequency) {
thetaUpdate = 0;
theta++;
}
else {
thetaUpdate++;
}
if (hueUpdate >= hueUpdateFrequency) {
hueUpdate = 0;
hue++;
}
else {
hueUpdate++;
}
return 0;
}
};
#endif

View file

@ -0,0 +1,298 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef Patterns_H
#define Patterns_H
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
#include "Vector.h"
#include "Boid.h"
#include "Attractor.h"
/*
* Note from mrfaptastic:
*
* Commented out patterns are due to the fact they either didn't work properly with a non-square display,
* or from my personal opinion, are crap.
*/
#include "PatternTest.h"
//#include "PatternNoiseSmearing.h" // Doesn't seem to work, omitting.
#include "PatternSpiro.h"
#include "PatternRadar.h"
#include "PatternSwirl.h"
#include "PatternPendulumWave.h"
#include "PatternFlowField.h"
#include "PatternIncrementalDrift.h"
//#include "PatternIncrementalDrift2.h" // Doesn't seem to work, omitting.
#include "PatternMunch.h"
#include "PatternElectricMandala.h"
//#include "PatternSpin.h" // Doesn't seem to work, omitting.
#include "PatternSimplexNoise.h"
#include "PatternWave.h"
#include "PatternAttract.h"
//#include "PatternBounce.h" // Doesn't seem to work, omitting.
#include "PatternFlock.h"
#include "PatternInfinity.h"
#include "PatternPlasma.h"
#include "PatternSnake.h"
//#include "PatternInvaders.h" // Doesn't seem to work, omitting.
//#include "PatternCube.h" // Doesn't seem to work, omitting.
//#include "PatternFire.h" // Doesn't seem to work, omitting.
#include "PatternLife.h"
#include "PatternMaze.h"
//#include "PatternPulse.h" // Doesn't seem to work, omitting.
//#include "PatternSpark.h" // Doesn't seem to work, omitting.
#include "PatternSpiral.h"
class Patterns : public Playlist {
private:
PatternTest patternTest;
// PatternRainbowFlag rainbowFlag; // doesn't work
// PatternPaletteSmear paletteSmear;
// PatternMultipleStream multipleStream; // doesn't work
// PatternMultipleStream2 multipleStream2; // doesn't work
// PatternMultipleStream3 multipleStream3; // doesn't work
// PatternMultipleStream4 multipleStream4; // doesn't work
// PatternMultipleStream5 multipleStream5; // doesn't work
// PatternMultipleStream8 multipleStream8; // doesn't work
PatternSpiro spiro;
// PatternRadar radar;
PatternSwirl swirl;
PatternPendulumWave pendulumWave;
PatternFlowField flowField;
PatternIncrementalDrift incrementalDrift;
// PatternIncrementalDrift2 incrementalDrift2;
PatternMunch munch;
PatternElectricMandala electricMandala;
// PatternSpin spin;
PatternSimplexNoise simplexNoise;
PatternWave wave;
PatternAttract attract;
// PatternBounce bounce;
PatternFlock flock;
PatternInfinity infinity;
PatternPlasma plasma;
// PatternInvadersSmall invadersSmall;
// PatternInvadersMedium invadersMedium;
// PatternInvadersLarge invadersLarge;
PatternSnake snake;
// PatternCube cube;
// PatternFire fire;
PatternLife life;
PatternMaze maze;
// PatternPulse pulse;
// PatternSpark spark;
PatternSpiral spiral;
int currentIndex = 0;
Drawable* currentItem;
int getCurrentIndex() {
return currentIndex;
}
//const static int PATTERN_COUNT = 37;
const static int PATTERN_COUNT = 17;
Drawable* shuffledItems[PATTERN_COUNT];
Drawable* items[PATTERN_COUNT] = {
// &patternTest, // ok
&spiro, // cool
// &paletteSmear, // fail
// &multipleStream, // fail
// &multipleStream8,// fail
// &multipleStream5,// fail
// &multipleStream3,// fail
// &radar, // fail
// &multipleStream4, // fail
// &multipleStream2, // fail
&life, // ok
&flowField,
&pendulumWave, //11 ok
&incrementalDrift, //12 ok
// &incrementalDrift2, // 13 fail
&munch, // 14 ok
&electricMandala, // 15 ok
// &spin, // 16 ok but repeditivev
&simplexNoise, // 17 - cool!
&wave, // 18 ok
// &rainbowFlag, //20 // fail
&attract, // 21 ok
&swirl, // 22
// &bounce, // boncing line crap
&flock, // works
&infinity, // works
&plasma, // works
// &invadersSmall, // works ish
// &invadersMedium, // fail
// &invadersLarge, // fail
&snake, // ok
// &cube, // works ish
// &fire, // ok ish
&maze, // ok
// &pulse,// fail
// &spark, // same as fire
&spiral, // ok
};
public:
Patterns() {
// add the items to the shuffledItems array
for (int a = 0; a < PATTERN_COUNT; a++) {
shuffledItems[a] = items[a];
}
shuffleItems();
this->currentItem = items[0];
this->currentItem->start();
}
char* Drawable::name = (char *)"Patterns";
void stop() {
if (currentItem)
currentItem->stop();
}
void start() {
if (currentItem)
currentItem->start();
}
void move(int step) {
currentIndex += step;
if (currentIndex >= PATTERN_COUNT) currentIndex = 0;
else if (currentIndex < 0) currentIndex = PATTERN_COUNT - 1;
if (effects.paletteIndex == effects.RandomPaletteIndex)
effects.RandomPalette();
moveTo(currentIndex);
//if (!isTimeAvailable && currentItem == &analogClock)
// move(step);
}
void moveRandom(int step) {
currentIndex += step;
if (currentIndex >= PATTERN_COUNT) currentIndex = 0;
else if (currentIndex < 0) currentIndex = PATTERN_COUNT - 1;
if (effects.paletteIndex == effects.RandomPaletteIndex)
effects.RandomPalette();
if (currentItem)
currentItem->stop();
currentItem = shuffledItems[currentIndex];
if (currentItem)
currentItem->start();
// if (!isTimeAvailable && currentItem == &analogClock)
// moveRandom(step);
}
void shuffleItems() {
for (int a = 0; a < PATTERN_COUNT; a++)
{
int r = random(a, PATTERN_COUNT);
Drawable* temp = shuffledItems[a];
shuffledItems[a] = shuffledItems[r];
shuffledItems[r] = temp;
}
}
unsigned int drawFrame() {
return currentItem->drawFrame();
}
void listPatterns() {
Serial.println(F("{"));
Serial.print(F(" \"count\": "));
Serial.print(PATTERN_COUNT);
Serial.println(",");
Serial.println(F(" \"results\": ["));
for (int i = 0; i < PATTERN_COUNT; i++) {
Serial.print(F(" \""));
Serial.print(i, DEC);
Serial.print(F(": "));
Serial.print(items[i]->name);
if (i == PATTERN_COUNT - 1)
Serial.println(F("\""));
else
Serial.println(F("\","));
}
Serial.println(" ]");
Serial.println("}");
}
char * getCurrentPatternName()
{
return currentItem->name;
}
void moveTo(int index) {
if (currentItem)
currentItem->stop();
currentIndex = index;
currentItem = items[currentIndex];
if (currentItem)
currentItem->start();
}
bool setPattern(String name) {
for (int i = 0; i < PATTERN_COUNT; i++) {
if (name.compareTo(items[i]->name) == 0) {
moveTo(i);
return true;
}
}
return false;
}
bool setPattern(int index) {
if (index >= PATTERN_COUNT || index < 0)
return false;
moveTo(index);
return true;
}
};
#endif

View file

@ -0,0 +1,39 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef Playlist_H
#define Playlist_H
class Playlist : public Drawable {
public:
virtual bool isPlaylist() {
return true;
}
boolean isCurrentItemFinished = true;
virtual void move(int step) = 0;
virtual void moveRandom(int step) = 0;
virtual int getCurrentIndex();
};
#endif

View file

@ -0,0 +1,6 @@
A port of Aurora visualisations
======
Not all of the visualisations have been ported. About 17 of 37 work, or have been included as I think they look best.
Original source: https://github.com/pixelmatix/aurora

View file

@ -0,0 +1,169 @@
/*
* Aurora: https://github.com/pixelmatix/aurora
* Copyright (c) 2014 Jason Coon
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef Vector_H
#define Vector_H
template <class T>
class Vector2 {
public:
T x, y;
Vector2() :x(0), y(0) {}
Vector2(T x, T y) : x(x), y(y) {}
Vector2(const Vector2& v) : x(v.x), y(v.y) {}
Vector2& operator=(const Vector2& v) {
x = v.x;
y = v.y;
return *this;
}
bool isEmpty() {
return x == 0 && y == 0;
}
bool operator==(Vector2& v) {
return x == v.x && y == v.y;
}
bool operator!=(Vector2& v) {
return !(x == y);
}
Vector2 operator+(Vector2& v) {
return Vector2(x + v.x, y + v.y);
}
Vector2 operator-(Vector2& v) {
return Vector2(x - v.x, y - v.y);
}
Vector2& operator+=(Vector2& v) {
x += v.x;
y += v.y;
return *this;
}
Vector2& operator-=(Vector2& v) {
x -= v.x;
y -= v.y;
return *this;
}
Vector2 operator+(double s) {
return Vector2(x + s, y + s);
}
Vector2 operator-(double s) {
return Vector2(x - s, y - s);
}
Vector2 operator*(double s) {
return Vector2(x * s, y * s);
}
Vector2 operator/(double s) {
return Vector2(x / s, y / s);
}
Vector2& operator+=(double s) {
x += s;
y += s;
return *this;
}
Vector2& operator-=(double s) {
x -= s;
y -= s;
return *this;
}
Vector2& operator*=(double s) {
x *= s;
y *= s;
return *this;
}
Vector2& operator/=(double s) {
x /= s;
y /= s;
return *this;
}
void set(T x, T y) {
this->x = x;
this->y = y;
}
void rotate(double deg) {
double theta = deg / 180.0 * M_PI;
double c = cos(theta);
double s = sin(theta);
double tx = x * c - y * s;
double ty = x * s + y * c;
x = tx;
y = ty;
}
Vector2& normalize() {
if (length() == 0) return *this;
*this *= (1.0 / length());
return *this;
}
float dist(Vector2 v) const {
Vector2 d(v.x - x, v.y - y);
return d.length();
}
float length() const {
return sqrt(x * x + y * y);
}
float mag() const {
return length();
}
float magSq() {
return (x * x + y * y);
}
void truncate(double length) {
double angle = atan2f(y, x);
x = length * cos(angle);
y = length * sin(angle);
}
Vector2 ortho() const {
return Vector2(y, -x);
}
static float dot(Vector2 v1, Vector2 v2) {
return v1.x * v2.x + v1.y * v2.y;
}
static float cross(Vector2 v1, Vector2 v2) {
return (v1.x * v2.y) - (v1.y * v2.x);
}
void limit(float max) {
if (magSq() > max*max) {
normalize();
*this *= max;
}
}
};
typedef Vector2<float> PVector;
#endif