diff options
author | Daniel Garcia <danielgarcia@gmail.com> | 2014-09-30 04:27:35 +0400 |
---|---|---|
committer | Daniel Garcia <danielgarcia@gmail.com> | 2014-09-30 04:27:35 +0400 |
commit | 4bb9ec547d95c895e24bf1d6f5c08fd61528a766 (patch) | |
tree | 18bcec7035f4e897cd1b479f808ed6f9fcecb35f | |
parent | cbd2b2e56a10f4d897f89015521f6eda351d85f1 (diff) | |
parent | 912d3c38bab3a69d42de487b8bde92ca0cd3ab12 (diff) |
Merge branch 'FastLED2.1' of https://github.com/FastLED/FastLED into FastLED2.1
-rw-r--r-- | colorutils.cpp | 75 | ||||
-rw-r--r-- | colorutils.h | 25 | ||||
-rw-r--r-- | examples/Fire2012/Fire2012.ino | 2 | ||||
-rw-r--r-- | examples/Fire2012WithPalette/Fire2012WithPalette.ino | 2 | ||||
-rw-r--r-- | lib8tion.h | 65 |
5 files changed, 160 insertions, 9 deletions
diff --git a/colorutils.cpp b/colorutils.cpp index ccaa646f..0f8d3832 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -319,6 +319,81 @@ CRGB* blend( const CRGB* src1, const CRGB* src2, CRGB* dest, uint16_t count, fra +CHSV& nblend( CHSV& existing, const CHSV& overlay, fract8 amountOfOverlay, TGradientDirectionCode directionCode) +{ + if( amountOfOverlay == 0) { + return existing; + } + + if( amountOfOverlay == 255) { + existing = overlay; + return existing; + } + + fract8 amountOfKeep = 256 - amountOfOverlay; + + uint8_t huedelta8 = overlay.hue - existing.hue; + + if( directionCode == SHORTEST_HUES ) { + directionCode = FORWARD_HUES; + if( huedelta8 > 127) { + directionCode = BACKWARD_HUES; + } + } + + if( directionCode == LONGEST_HUES ) { + directionCode = FORWARD_HUES; + if( huedelta8 < 128) { + directionCode = BACKWARD_HUES; + } + } + + if( directionCode == FORWARD_HUES) { + existing.hue = existing.hue + scale8( huedelta8, amountOfOverlay); + } + else /* directionCode == BACKWARD_HUES */ + { + huedelta8 = -huedelta8; + existing.hue = existing.hue - scale8( huedelta8, amountOfOverlay); + } + + existing.sat = scale8_LEAVING_R1_DIRTY( existing.sat, amountOfKeep) + + scale8_LEAVING_R1_DIRTY( overlay.sat, amountOfOverlay); + existing.val = scale8_LEAVING_R1_DIRTY( existing.val, amountOfKeep) + + scale8_LEAVING_R1_DIRTY( overlay.val, amountOfOverlay); + + cleanup_R1(); + + return existing; +} + + + +void nblend( CHSV* existing, CHSV* overlay, uint16_t count, fract8 amountOfOverlay, TGradientDirectionCode directionCode ) +{ + for( uint16_t i = count; i; i--) { + nblend( *existing, *overlay, amountOfOverlay, directionCode); + existing++; + overlay++; + } +} + +CHSV blend( const CHSV& p1, const CHSV& p2, fract8 amountOfP2, TGradientDirectionCode directionCode ) +{ + CHSV nu(p1); + nblend( nu, p2, amountOfP2, directionCode); + return nu; +} + +CHSV* blend( const CHSV* src1, const CHSV* src2, CHSV* dest, uint16_t count, fract8 amountOfsrc2, TGradientDirectionCode directionCode ) +{ + for( uint16_t i = count; i; i--) { + dest[i] = blend(src1[i], src2[i], amountOfsrc2, directionCode); + } + return dest; +} + + // CRGB HeatColor( uint8_t temperature) // diff --git a/colorutils.h b/colorutils.h index c986838b..181970e7 100644 --- a/colorutils.h +++ b/colorutils.h @@ -96,25 +96,38 @@ void nscale8( CRGB* leds, uint16_t num_leds, uint8_t scale); // Pixel blending // -// blend - computes an RGB-blended some fraction of the way -// between two other RGB colors. +// blend - computes a new color blended some fraction of the way +// between two other colors. CRGB blend( const CRGB& p1, const CRGB& p2, fract8 amountOfP2 ); -// blend - computes an RGB-blended array of colors, each +CHSV blend( const CHSV& p1, const CHSV& p2, fract8 amountOfP2, + TGradientDirectionCode directionCode = SHORTEST_HUES ); + +// blend - computes a new color blended array of colors, each // a given fraction of the way between corresponding // elements of two source arrays of colors. // Useful for blending palettes. CRGB* blend( const CRGB* src1, const CRGB* src2, CRGB* dest, uint16_t count, fract8 amountOfsrc2 ); -// nblend - destructively modifies one RGB color, blending -// in a given fraction of an overlay RGB color +CHSV* blend( const CHSV* src1, const CHSV* src2, CHSV* dest, + uint16_t count, fract8 amountOfsrc2, + TGradientDirectionCode directionCode = SHORTEST_HUES ); + +// nblend - destructively modifies one color, blending +// in a given fraction of an overlay color CRGB& nblend( CRGB& existing, const CRGB& overlay, fract8 amountOfOverlay ); +CHSV& nblend( CHSV& existing, const CHSV& overlay, fract8 amountOfOverlay, + TGradientDirectionCode directionCode = SHORTEST_HUES ); + // nblend - destructively blends a given fraction of -// a new RGB array into an existing RGB array +// a new color array into an existing color array void nblend( CRGB* existing, CRGB* overlay, uint16_t count, fract8 amountOfOverlay); +void nblend( CHSV* existing, CHSV* overlay, uint16_t count, fract8 amountOfOverlay, + TGradientDirectionCode directionCode = SHORTEST_HUES); + // CRGB HeatColor( uint8_t temperature) diff --git a/examples/Fire2012/Fire2012.ino b/examples/Fire2012/Fire2012.ino index 73703426..0929e2f2 100644 --- a/examples/Fire2012/Fire2012.ino +++ b/examples/Fire2012/Fire2012.ino @@ -78,7 +78,7 @@ void Fire2012() } // Step 2. Heat from each cell drifts 'up' and diffuses a little - for( int k= NUM_LEDS - 3; k > 0; k--) { + for( int k= NUM_LEDS - 1; k >= 2; k--) { heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3; } diff --git a/examples/Fire2012WithPalette/Fire2012WithPalette.ino b/examples/Fire2012WithPalette/Fire2012WithPalette.ino index 1208a589..41b9a247 100644 --- a/examples/Fire2012WithPalette/Fire2012WithPalette.ino +++ b/examples/Fire2012WithPalette/Fire2012WithPalette.ino @@ -134,7 +134,7 @@ void Fire2012WithPalette() } // Step 2. Heat from each cell drifts 'up' and diffuses a little - for( int k= NUM_LEDS - 3; k > 0; k--) { + for( int k= NUM_LEDS - 1; k >= 2; k--) { heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3; } @@ -105,13 +105,19 @@ quadwave8( x) triwave8( x) - + - Square root for 16-bit integers. About three times + faster and five times smaller than Arduino's built-in + generic 32-bit sqrt routine. + sqrt16( uint16_t x ) == sqrt( x) + - Dimming and brightening functions for 8-bit light values. dim8_video( x) == scale8_video( x, x) dim8_raw( x) == scale8( x, x) + dim8_lin( x) == (x<128) ? ((x+1)/2) : scale8(x,x) brighten8_video( x) == 255 - dim8_video( 255 - x) brighten8_raw( x) == 255 - dim8_raw( 255 - x) + brighten8_lin( x) == 255 - dim8_lin( 255 - x) The dimming functions in particular are suitable for making LED light output appear more 'linear'. @@ -996,6 +1002,17 @@ LIB8STATIC uint8_t dim8_video( uint8_t x) return scale8_video( x, x); } +LIB8STATIC uint8_t dim8_lin( uint8_t x ) +{ + if( x & 0x80 ) { + x = scale8( x, x); + } else { + x += 1; + x /= 2; + } + return x; +} + LIB8STATIC uint8_t brighten8_raw( uint8_t x) { uint8_t ix = 255 - x; @@ -1008,6 +1025,18 @@ LIB8STATIC uint8_t brighten8_video( uint8_t x) return 255 - scale8_video( ix, ix); } +LIB8STATIC uint8_t brighten8_lin( uint8_t x ) +{ + uint8_t ix = 255 - x; + if( ix & 0x80 ) { + ix = scale8( ix, ix); + } else { + ix += 1; + ix /= 2; + } + return 255 - ix; +} + /////////////////////////////////////////////////////////////////////// // A 16-bit PNRG good enough for LED animations @@ -1578,6 +1607,40 @@ LIB8STATIC uint8_t cubicwave8(uint8_t in) +// sqrt16: square root for 16-bit integers +// About three times faster and five times smaller +// than Arduino's general sqrt on AVR. +LIB8STATIC uint8_t sqrt16(uint16_t x) +{ + if( x <= 1) { + return x; + } + + uint8_t low = 1; // lower bound + uint8_t hi, mid; + + if( x > 7904) { + hi = 255; + } else { + hi = (x >> 5) + 8; // initial estimate for upper bound + } + + do { + mid = (low + hi) >> 1; + if ((mid * mid) > x) { + hi = mid - 1; + } else { + if( mid == 255) { + return 255; + } + low = mid + 1; + } + } while (hi >= low); + + return low - 1; +} + + template<class T, int F, int I> class q { T i:I; T f:F; |