Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kriegsman <kriegsman@tr.org>2014-10-05 22:42:40 +0400
committerMark Kriegsman <kriegsman@tr.org>2014-10-05 22:42:40 +0400
commit73989e3f0bd417fd5746292ca73fe27aa6fc7cc9 (patch)
tree71e23082d3e5ed83031cd60891b40e9c1a2e8c0b
parent91c36a8737bc807e26c61c21155504b08e6b5741 (diff)
Fix for fill_gradient, switch to templates for a few functions to allow use on CHSV arrays as well as CRGB arrays, e.g., if there ever were such a thing as CHSVPalette.
-rw-r--r--colorutils.cpp124
-rw-r--r--colorutils.h139
2 files changed, 156 insertions, 107 deletions
diff --git a/colorutils.cpp b/colorutils.cpp
index 0f8d3832..6a12fb11 100644
--- a/colorutils.cpp
+++ b/colorutils.cpp
@@ -6,14 +6,31 @@
#include "colorutils.h"
-void fill_solid( struct CRGB * pFirstLED, int numToFill,
- const struct CRGB& color)
+
+
+void fill_solid( struct CRGB * leds, int numToFill,
+ const struct CRGB& color)
+{
+ for( int i = 0; i < numToFill; i++) {
+ leds[i] = color;
+ }
+}
+
+void fill_solid( struct CHSV * targetArray, int numToFill,
+ const struct CHSV& hsvColor)
{
for( int i = 0; i < numToFill; i++) {
- pFirstLED[i] = color;
+ targetArray[i] = hsvColor;
}
}
+
+// void fill_solid( struct CRGB* targetArray, int numToFill,
+// const struct CHSV& hsvColor)
+// {
+// fill_solid<CRGB>( targetArray, numToFill, (CRGB) hsvColor);
+// }
+
void fill_rainbow( struct CRGB * pFirstLED, int numToFill,
uint8_t initialhue,
uint8_t deltahue )
@@ -28,74 +45,21 @@ 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 )
+void fill_rainbow( struct CHSV * targetArray, int numToFill,
+ uint8_t initialhue,
+ uint8_t deltahue )
{
- // 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;
+ CHSV hsv;
+ hsv.hue = initialhue;
+ hsv.val = 255;
+ hsv.sat = 255;
+ for( int i = 0; i < numToFill; i++) {
+ targetArray[i] = hsv;
+ hsv.hue += deltahue;
}
}
+
void fill_gradient_RGB( CRGB* leds,
uint16_t startpos, CRGB startcolor,
uint16_t endpos, CRGB endcolor )
@@ -136,32 +100,6 @@ void fill_gradient_RGB( CRGB* leds,
}
}
-
-void fill_gradient( CRGB* leds, uint16_t numLeds, const CHSV& c1, const CHSV& c2, TGradientDirectionCode directionCode )
-{
- uint16_t last = numLeds - 1;
- fill_gradient( leds, 0, c1, last, c2, directionCode);
-}
-
-
-void fill_gradient( CRGB* leds, uint16_t numLeds, const CHSV& c1, const CHSV& c2, const CHSV& c3, TGradientDirectionCode directionCode )
-{
- uint16_t half = (numLeds / 2);
- uint16_t last = numLeds - 1;
- fill_gradient( leds, 0, c1, half, c2, directionCode);
- fill_gradient( leds, half, c2, last, c3, directionCode);
-}
-
-void fill_gradient( CRGB* leds, uint16_t numLeds, const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4, TGradientDirectionCode directionCode )
-{
- uint16_t onethird = (numLeds / 3);
- uint16_t twothirds = ((numLeds * 2) / 3);
- uint16_t last = numLeds - 1;
- fill_gradient( leds, 0, c1, onethird, c2, directionCode);
- fill_gradient( leds, onethird, c2, twothirds, c3, directionCode);
- fill_gradient( leds, twothirds, c3, last, c4, directionCode);
-}
-
#if 0
void fill_gradient( const CHSV& c1, const CHSV& c2)
{
diff --git a/colorutils.h b/colorutils.h
index 181970e7..c2e1ec65 100644
--- a/colorutils.h
+++ b/colorutils.h
@@ -7,17 +7,27 @@
// fill_solid - fill a range of LEDs with a solid color
-void fill_solid( struct CRGB * pFirstLED, int numToFill,
+// Example: fill_solid( leds, NUM_LEDS, CRGB(50,0,200));
+
+void fill_solid( struct CRGB * leds, int numToFill,
const struct CRGB& color);
+void fill_solid( struct CHSV* targetArray, int numToFill,
+ const struct CHSV& hsvColor);
+
+
// fill_rainbow - fill a range of LEDs with a rainbow of colors, at
// full saturation and full value (brightness)
void fill_rainbow( struct CRGB * pFirstLED, int numToFill,
uint8_t initialhue,
uint8_t deltahue = 5);
+
+void fill_rainbow( struct CHSV * targetArray, int numToFill,
+ uint8_t initialhue,
+ uint8_t deltahue = 5);
-// fill_gradient - fill a range of LEDs with a smooth HSV gradient
+// fill_gradient - fill an array of colors with a smooth HSV 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
@@ -31,24 +41,125 @@ void fill_rainbow( struct CRGB * pFirstLED, int numToFill,
// The default is SHORTEST_HUES, as this is nearly
// always what is wanted.
//
+// fill_gradient can write the gradient colors EITHER
+// (1) into an array of CRGBs (e.g., into leds[] array, or an RGB Palette)
+// OR
+// (2) into an array of CHSVs (e.g. an HSV Palette).
+//
+// In the case of writing into a CRGB array, the gradient is
+// computed in HSV space, and then HSV values are converted to RGB
+// as they're written into the RGB array.
+
typedef enum { FORWARD_HUES, BACKWARD_HUES, SHORTEST_HUES, LONGEST_HUES } TGradientDirectionCode;
-void fill_gradient( struct CRGB* leds,
+
+
+#define saccum87 int16_t
+
+template <typename T>
+void fill_gradient( T* targetArray,
uint16_t startpos, CHSV startcolor,
uint16_t endpos, CHSV endcolor,
- TGradientDirectionCode directionCode = SHORTEST_HUES );
+ TGradientDirectionCode directionCode = SHORTEST_HUES )
+{
+ // 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;
+ int16_t divisor = pixeldistance ? pixeldistance : 1;
+
+ saccum87 huedelta87 = huedistance87 / divisor;
+ saccum87 satdelta87 = satdistance87 / divisor;
+ saccum87 valdelta87 = valdistance87 / divisor;
+
+ huedelta87 *= 2;
+ satdelta87 *= 2;
+ valdelta87 *= 2;
+
+ accum88 hue88 = startcolor.hue << 8;
+ accum88 sat88 = startcolor.sat << 8;
+ accum88 val88 = startcolor.val << 8;
+ for( uint16_t i = startpos; i <= endpos; i++) {
+ targetArray[i] = CHSV( hue88 >> 8, sat88 >> 8, val88 >> 8);
+ hue88 += huedelta87;
+ sat88 += satdelta87;
+ val88 += valdelta87;
+ }
+}
+
-// Convenience functions to fill a range of leds[] with a
+// Convenience functions to fill an array of colors with a
// two-color, three-color, or four-color gradient
-void fill_gradient( struct CRGB* leds, uint16_t numLeds,
- const CHSV& c1, const CHSV& c2,
- TGradientDirectionCode directionCode = SHORTEST_HUES );
-void fill_gradient( struct CRGB* leds, uint16_t numLeds,
- const CHSV& c1, const CHSV& c2, const CHSV& c3,
- TGradientDirectionCode directionCode = SHORTEST_HUES );
-void fill_gradient( struct CRGB* leds, uint16_t numLeds,
- const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4,
- TGradientDirectionCode directionCode = SHORTEST_HUES );
+template <typename T>
+void fill_gradient( T* targetArray, uint16_t numLeds, const CHSV& c1, const CHSV& c2,
+ TGradientDirectionCode directionCode = SHORTEST_HUES )
+{
+ uint16_t last = numLeds - 1;
+ fill_gradient( targetArray, 0, c1, last, c2, directionCode);
+}
+
+template <typename T>
+void fill_gradient( T* targetArray, uint16_t numLeds,
+ const CHSV& c1, const CHSV& c2, const CHSV& c3,
+ TGradientDirectionCode directionCode = SHORTEST_HUES )
+{
+ uint16_t half = (numLeds / 2);
+ uint16_t last = numLeds - 1;
+ fill_gradient( targetArray, 0, c1, half, c2, directionCode);
+ fill_gradient( targetArray, half, c2, last, c3, directionCode);
+}
+
+template <typename T>
+void fill_gradient( T* targetArray, uint16_t numLeds,
+ const CHSV& c1, const CHSV& c2, const CHSV& c3, const CHSV& c4,
+ TGradientDirectionCode directionCode = SHORTEST_HUES )
+{
+ uint16_t onethird = (numLeds / 3);
+ uint16_t twothirds = ((numLeds * 2) / 3);
+ uint16_t last = numLeds - 1;
+ fill_gradient( targetArray, 0, c1, onethird, c2, directionCode);
+ fill_gradient( targetArray, onethird, c2, twothirds, c3, directionCode);
+ fill_gradient( targetArray, twothirds, c3, last, c4, directionCode);
+}
// convenience synonym
#define fill_gradient_HSV fill_gradient