add bouncing balls effect

This commit is contained in:
fishbone-git 2019-12-10 20:06:00 +01:00
parent 4ffeb05120
commit 7ca1970fff
2 changed files with 70 additions and 3 deletions

View File

@ -2285,3 +2285,67 @@ uint16_t WS2812FX::mode_spots_fade()
uint16_t tr = (t >> 1) + (t >> 2);
return spots_base(tr);
}
/*
* Bouncing Balls Effect
* Adapted from: https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
*/
uint16_t WS2812FX::mode_BouncingBalls(void) {
// number of balls based on intensity setting,
// only has 4 for a few of the higher settings as there is no colour selection
// fourth ball is a random colour
int balls = int(((SEGMENT.intensity * 6.2) / 255) + 1);
// ideally use speed for gravity effect on the bounce
float Gravity = -9.81;
const int maxBallCount = 7;
static float Height[maxBallCount];
static float ImpactVelocity[maxBallCount];
static int Position[maxBallCount];
static float TimeSinceLastBounce[maxBallCount];
static long ClockTimeSinceLastBounce[maxBallCount];
static int StartHeight = 1; // height in metres (strip length)
static float Dampening[maxBallCount] = {0}; // Coefficient of Restitution (bounce damping)
static float ImpactVelocityStart=sqrt( -2 * Gravity * StartHeight);
// Different from the examples, to allow for initialisation of the first bounce
if (Dampening[0] == 0) {
for (int i = 0 ; i < maxBallCount ; i++) {
ClockTimeSinceLastBounce[i] = millis();
ImpactVelocity[i] = ImpactVelocityStart;
TimeSinceLastBounce[i] = 0;
Dampening[i] = 0.90 - float(i)/pow(maxBallCount,2);
}
}
for (int i = 0 ; i < balls ; i++) {
TimeSinceLastBounce[i] = millis() - ClockTimeSinceLastBounce[i];
Height[i] = 0.5 * Gravity * pow( TimeSinceLastBounce[i]/1000 , 2.0 ) + ImpactVelocity[i] * TimeSinceLastBounce[i]/1000;
if ( Height[i] < 0 ) {
Height[i] = 0;
ImpactVelocity[i] = Dampening[i] * ImpactVelocity[i];
ClockTimeSinceLastBounce[i] = millis();
if ( ImpactVelocity[i] < 0.01 ) {
ImpactVelocity[i] = ImpactVelocityStart;
}
}
Position[i] = round( Height[i] * (SEGLEN - 1) / StartHeight);
}
fill(BLACK);
for (int i = 0 ; i < balls ; i++) {
uint32_t color = SEGCOLOR(i % NUM_COLORS);
if (!color) {
color = color_wheel(random8());
}
setPixelColor(Position[i],color);
}
return 20;
}

View File

@ -84,7 +84,7 @@
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
#define MODE_COUNT 87
#define MODE_COUNT 88
#define FX_MODE_STATIC 0
#define FX_MODE_BLINK 1
@ -173,6 +173,7 @@
#define FX_MODE_TRI_STATIC_PATTERN 84
#define FX_MODE_SPOTS 85
#define FX_MODE_SPOTS_FADE 86
#define FX_MODE_BOUNCINGBALLS 87
class WS2812FX {
@ -317,6 +318,7 @@ class WS2812FX {
_mode[FX_MODE_TRI_STATIC_PATTERN] = &WS2812FX::mode_tri_static_pattern;
_mode[FX_MODE_SPOTS] = &WS2812FX::mode_spots;
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
_mode[FX_MODE_BOUNCINGBALLS] = &WS2812FX::mode_BouncingBalls;
_brightness = DEFAULT_BRIGHTNESS;
currentPalette = CRGBPalette16(CRGB::Black);
@ -497,7 +499,8 @@ class WS2812FX {
mode_static_pattern(void),
mode_tri_static_pattern(void),
mode_spots(void),
mode_spots_fade(void);
mode_spots_fade(void),
mode_BouncingBalls(void);
private:
NeoPixelWrapper *bus;
@ -570,7 +573,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([
"Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
"Dual Scanner","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Smooth Meteor","Railway","Ripple",
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade"
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Bouncing Balls"
])=====";