diff options
author | Mark Kriegsman <kriegsman@tr.org> | 2014-05-31 16:41:48 +0400 |
---|---|---|
committer | Mark Kriegsman <kriegsman@tr.org> | 2014-05-31 16:41:48 +0400 |
commit | 19bcc72623e7a28788f1dbd4307fb7a445029f79 (patch) | |
tree | f87aaf861d094b069a5e2b24cc53ac3d521ef965 | |
parent | 7947112768eff495cafa5bcce92a29746257dd24 (diff) |
Added fill_gradient
-rw-r--r-- | colorutils.cpp | 68 | ||||
-rw-r--r-- | colorutils.h | 23 | ||||
-rw-r--r-- | preview_changes.txt | 1 |
3 files changed, 92 insertions, 0 deletions
diff --git a/colorutils.cpp b/colorutils.cpp index e0a82882..12e9b0ad 100644 --- a/colorutils.cpp +++ b/colorutils.cpp @@ -27,6 +27,74 @@ void fill_rainbow( struct CRGB * pFirstLED, int numToFill, } +#define saccum87 int16_t + +void fill_gradient( CRGB* leds, + uint16_t startpos, CHSV startcolor, + uint16_t endpos, CHSV endcolor, + TGradientDirectionCode directionCode ) +{ + // if the points are in the wrong order, straighten them + if( endpos < startpos ) { + uint16_t t = endpos; + CHSV tc = endcolor; + startpos = t; + startcolor = tc; + endcolor = startcolor; + endpos = startpos; + } + + saccum87 huedistance87; + saccum87 satdistance87; + saccum87 valdistance87; + + satdistance87 = (endcolor.sat - startcolor.sat) << 7; + valdistance87 = (endcolor.val - startcolor.val) << 7; + + uint8_t huedelta8 = endcolor.hue - startcolor.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) { + huedistance87 = huedelta8 << 7; + } + else /* directionCode == BACKWARD_HUES */ + { + huedistance87 = (uint8_t)(256 - huedelta8) << 7; + huedistance87 = -huedistance87; + } + + uint16_t pixeldistance = endpos - startpos; + uint16_t p2 = pixeldistance / 2; + int16_t divisor = p2 ? p2 : 1; + saccum87 huedelta87 = huedistance87 / divisor; + saccum87 satdelta87 = satdistance87 / divisor; + saccum87 valdelta87 = valdistance87 / divisor; + + accum88 hue88 = startcolor.hue << 8; + accum88 sat88 = startcolor.sat << 8; + accum88 val88 = startcolor.val << 8; + for( uint16_t i = startpos; i <= endpos; i++) { + leds[i] = CHSV( hue88 >> 8, sat88 >> 8, val88 >> 8); + hue88 += huedelta87; + sat88 += satdelta87; + val88 += valdelta87; + } +} + + void nscale8_video( CRGB* leds, uint16_t num_leds, uint8_t scale) { diff --git a/colorutils.h b/colorutils.h index 457aec57..44b2855b 100644 --- a/colorutils.h +++ b/colorutils.h @@ -15,6 +15,29 @@ void fill_rainbow( struct CRGB * pFirstLED, int numToFill, uint8_t deltahue = 5); +// fill_gradient - fill a range of LEDs with a smooth gradient +// between two specified HSV colors. +// Since 'hue' is a value around a color wheel, +// there are always two ways to sweep from one hue +// to another. +// This function lets you specify which way you want +// the hue gradient to sweep around the color wheel: +// FORWARD_HUES: hue always goes clockwise +// BACKWARD_HUES: hue always goes counter-clockwise +// SHORTEST_HUES: hue goes whichever way is shortest +// LONGEST_HUES: hue goes whichever way is longest +// The default is SHORTEST_HUES, as this is nearly +// always what is wanted. +// +typedef enum { FORWARD_HUES, BACKWARD_HUES, SHORTEST_HUES, LONGEST_HUES } TGradientDirectionCode; + +void fill_gradient( struct CRGB* leds, + uint16_t startpos, CHSV startcolor, + uint16_t endpos, CHSV endcolor, + TGradientDirectionCode directionCode = SHORTEST_HUES ); + + + // fadeLightBy and fade_video - reduce the brightness of an array // of pixels all at once. Guaranteed // to never fade all the way to black. diff --git a/preview_changes.txt b/preview_changes.txt index caa45100..bc69c59f 100644 --- a/preview_changes.txt +++ b/preview_changes.txt @@ -16,3 +16,4 @@ * Added map8 * Adjusted VIRTAL_BITS of dithering from a flickery 8 to a more solid 3 * Added array versions of fade_video, fade_raw, and some variations +* Added fill_gradient |