diff --git a/src/internal/HsbColor.cpp b/src/internal/HsbColor.cpp index 146ddb8..79d69dd 100644 --- a/src/internal/HsbColor.cpp +++ b/src/internal/HsbColor.cpp @@ -24,6 +24,7 @@ License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ +#include #include "RgbColor.h" #include "Rgb48Color.h" #include "HsbColor.h" diff --git a/src/internal/HsbColor.h b/src/internal/HsbColor.h index 939d5a1..bf9466b 100644 --- a/src/internal/HsbColor.h +++ b/src/internal/HsbColor.h @@ -26,8 +26,6 @@ License along with NeoPixel. If not, see -------------------------------------------------------------------------*/ #pragma once -#include - // ------------------------------------------------------------------------ // HsbColor represents a color object that is represented by Hue, Saturation, Brightness // component values. It contains helpful color routines to manipulate the diff --git a/src/internal/HslColor.cpp b/src/internal/HslColor.cpp index 92ae687..1442c88 100644 --- a/src/internal/HslColor.cpp +++ b/src/internal/HslColor.cpp @@ -25,6 +25,7 @@ License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ +#include #include "RgbColor.h" #include "Rgb48Color.h" #include "HslColor.h" diff --git a/src/internal/HslColor.h b/src/internal/HslColor.h index 3555a5c..44f9061 100644 --- a/src/internal/HslColor.h +++ b/src/internal/HslColor.h @@ -25,8 +25,6 @@ License along with NeoPixel. If not, see -------------------------------------------------------------------------*/ #pragma once -#include - // ------------------------------------------------------------------------ // HslColor represents a color object that is represented by Hue, Saturation, Lightness // component values. It contains helpful color routines to manipulate the diff --git a/src/internal/HtmlColor.cpp b/src/internal/HtmlColor.cpp index 018d58f..d24edbb 100644 --- a/src/internal/HtmlColor.cpp +++ b/src/internal/HtmlColor.cpp @@ -23,6 +23,8 @@ You should have received a copy of the GNU Lesser General Public License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ + +#include #include "HtmlColor.h" static inline char hexdigit(uint8_t v) diff --git a/src/internal/HtmlColorNameStrings.cpp b/src/internal/HtmlColorNameStrings.cpp index 87dda4b..6c71b33 100644 --- a/src/internal/HtmlColorNameStrings.cpp +++ b/src/internal/HtmlColorNameStrings.cpp @@ -24,6 +24,7 @@ License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ +#include #include "HtmlColorNameStrings.h" /* HTML4 color names */ diff --git a/src/internal/HtmlColorNameStrings.h b/src/internal/HtmlColorNameStrings.h index 86ffcf4..dcd30c6 100644 --- a/src/internal/HtmlColorNameStrings.h +++ b/src/internal/HtmlColorNameStrings.h @@ -26,8 +26,6 @@ License along with NeoPixel. If not, see #pragma once -#include - /* HTML4 color names */ extern const char c_HtmlNameAqua[] PROGMEM; extern const char c_HtmlNameBlack[] PROGMEM; diff --git a/src/internal/NeoEsp32I2sMethod.h b/src/internal/NeoEsp32I2sMethod.h index 291b25a..c594c70 100644 --- a/src/internal/NeoEsp32I2sMethod.h +++ b/src/internal/NeoEsp32I2sMethod.h @@ -32,7 +32,6 @@ License along with NeoPixel. If not, see extern "C" { -#include #include "Esp32_i2s.h" } diff --git a/src/internal/NeoEsp32I2sXMethod.h b/src/internal/NeoEsp32I2sXMethod.h index 2e8ee26..2a5a91c 100644 --- a/src/internal/NeoEsp32I2sXMethod.h +++ b/src/internal/NeoEsp32I2sXMethod.h @@ -31,7 +31,6 @@ License along with NeoPixel. If not, see extern "C" { -#include #include "Esp32_i2s.h" } diff --git a/src/internal/NeoEsp32RmtMethod.h b/src/internal/NeoEsp32RmtMethod.h index e4e3d85..3cf240b 100644 --- a/src/internal/NeoEsp32RmtMethod.h +++ b/src/internal/NeoEsp32RmtMethod.h @@ -43,8 +43,6 @@ Esp32-hal-rmt.h Esp32-hal-rmt.c */ -#include - extern "C" { #include diff --git a/src/internal/NeoEsp8266UartMethod.h b/src/internal/NeoEsp8266UartMethod.h index 2eb5228..dd3018c 100644 --- a/src/internal/NeoEsp8266UartMethod.h +++ b/src/internal/NeoEsp8266UartMethod.h @@ -27,7 +27,6 @@ License along with NeoPixel. If not, see #pragma once #ifdef ARDUINO_ARCH_ESP8266 -#include // this template method class is used to track the data being sent on the uart // when using the default serial ISR installed by the core diff --git a/src/internal/NeoPixelAnimator.cpp b/src/internal/NeoPixelAnimator.cpp index 55e74ae..b97565f 100644 --- a/src/internal/NeoPixelAnimator.cpp +++ b/src/internal/NeoPixelAnimator.cpp @@ -24,6 +24,7 @@ License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ +#include #include "NeoPixelBus.h" #include "NeoPixelAnimator.h" diff --git a/src/internal/NeoSegmentFeatures.h b/src/internal/NeoSegmentFeatures.h index 43ccad9..ef3a2fc 100644 --- a/src/internal/NeoSegmentFeatures.h +++ b/src/internal/NeoSegmentFeatures.h @@ -112,7 +112,7 @@ public: static void applyPixelColor(uint8_t* pPixels, uint16_t indexPixel, ColorObject color) { uint8_t* p = getPixelAddress(pPixels, indexPixel); - uint8_t commonSize = (PixelSize < color.SegmentCount) ? PixelSize : color.SegmentCount; + uint8_t commonSize = (PixelSize < color.Count) ? PixelSize : color.Count; for (uint8_t iSegment = 0; iSegment < commonSize; iSegment++) { *p++ = color.Segment[iSegment]; @@ -123,7 +123,7 @@ public: { ColorObject color; const uint8_t* p = getPixelAddress(pPixels, indexPixel); - uint8_t commonSize = (PixelSize < color.SegmentCount) ? PixelSize : color.SegmentCount; + uint8_t commonSize = (PixelSize < color.Count) ? PixelSize : color.Count; for (uint8_t iSegment = 0; iSegment < commonSize; iSegment++) { @@ -136,7 +136,7 @@ public: { ColorObject color; const uint8_t* p = getPixelAddress((const uint8_t*)pPixels, indexPixel); - uint8_t commonSize = (PixelSize < color.SegmentCount) ? PixelSize : color.SegmentCount; + uint8_t commonSize = (PixelSize < color.Count) ? PixelSize : color.Count; for (uint8_t iSegment = 0; iSegment < commonSize; iSegment++) { diff --git a/src/internal/Rgb16Color.h b/src/internal/Rgb16Color.h index d2fdd8c..19f7d96 100644 --- a/src/internal/Rgb16Color.h +++ b/src/internal/Rgb16Color.h @@ -25,7 +25,6 @@ License along with NeoPixel. If not, see -------------------------------------------------------------------------*/ #pragma once -#include #include "NeoSettings.h" #include "RgbColorBase.h" @@ -243,7 +242,16 @@ struct Rgb16Color : RgbColorBase return Rgb16Color(result.R, result.G, result.B); }; - + // progress - (0 - 255) value where 0 will return left and 255 will return right + // and a value between will blend the color weighted linearly between them + // ------------------------------------------------------------------------ + static Rgb16Color LinearBlend(const Rgb16Color& left, const Rgb16Color& right, uint8_t progress) + { + RgbColor result = RgbColor::LinearBlend(left, right, progress); + + return Rgb16Color(result.R, result.G, result.B); + }; + // ------------------------------------------------------------------------ // BilinearBlend between four colors by the amount defined by 2d variable // c00 - upper left quadrant color diff --git a/src/internal/Rgb48Color.cpp b/src/internal/Rgb48Color.cpp index 789047e..bcc43ce 100644 --- a/src/internal/Rgb48Color.cpp +++ b/src/internal/Rgb48Color.cpp @@ -24,6 +24,7 @@ License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ +#include #include "Rgb48Color.h" #include "RgbColor.h" #include "HslColor.h" @@ -135,9 +136,15 @@ void Rgb48Color::Lighten(uint16_t delta) Rgb48Color Rgb48Color::LinearBlend(const Rgb48Color& left, const Rgb48Color& right, float progress) { - return Rgb48Color( left.R + (((int32_t)right.R - left.R) * progress), - left.G + (((int32_t)right.G - left.G) * progress), - left.B + (((int32_t)right.B - left.B) * progress)); + return Rgb48Color( left.R + ((static_cast(right.R) - left.R) * progress), + left.G + ((static_cast(right.G) - left.G) * progress), + left.B + ((static_cast(right.B) - left.B) * progress)); +} +Rgb48Color Rgb48Color::LinearBlend(const Rgb48Color& left, const Rgb48Color& right, uint8_t progress) +{ + return Rgb48Color(left.R + (((static_cast(right.R) - left.R) * static_cast(progress) + 1) >> 8), + left.G + (((static_cast(right.G) - left.G) * static_cast(progress) + 1) >> 8), + left.B + (((static_cast(right.B) - left.B) * static_cast(progress) + 1) >> 8)); } Rgb48Color Rgb48Color::BilinearBlend(const Rgb48Color& c00, diff --git a/src/internal/Rgb48Color.h b/src/internal/Rgb48Color.h index a16dc86..f01e9be 100644 --- a/src/internal/Rgb48Color.h +++ b/src/internal/Rgb48Color.h @@ -25,7 +25,6 @@ License along with NeoPixel. If not, see -------------------------------------------------------------------------*/ #pragma once -#include #include "NeoSettings.h" #include "RgbColorBase.h" #include "RgbColor.h" @@ -107,6 +106,68 @@ struct Rgb48Color : RgbColorBase return !(*this == other); }; + // ------------------------------------------------------------------------ + // CompareTo method + // compares against another color with the given epsilon (delta allowed) + // returns the greatest difference of a set of elements, + // 0 = equal within epsilon delta + // negative - this is less than other + // positive - this is greater than other + // ------------------------------------------------------------------------ + int32_t CompareTo(const Rgb48Color& other, uint16_t epsilon = 256) + { + return _Compare(*this, other, epsilon); + } + + // ------------------------------------------------------------------------ + // Compare method + // compares two colors with the given epsilon (delta allowed) + // returns the greatest difference of a set of elements, + // 0 = equal within epsilon delta + // negative - this is less than other + // positive - this is greater than other + // ------------------------------------------------------------------------ + static int32_t Compare(const Rgb48Color& left, const Rgb48Color& right, uint16_t epsilon = 256) + { + return _Compare(left, right, epsilon); + } + + // ------------------------------------------------------------------------ + // operator [] - readonly + // access elements in order by index rather than R,G,B + // see static Count for the number of elements + // ------------------------------------------------------------------------ + uint16_t operator[](size_t idx) const + { + switch (idx) + { + case 0: + return R; + case 1: + return G; + default: + return B; + } + } + + // ------------------------------------------------------------------------ + // operator [] - read write + // access elements in order by index rather than R,G,B + // see static Count for the number of elements + // ------------------------------------------------------------------------ + uint16_t& operator[](size_t idx) + { + switch (idx) + { + case 0: + return R; + case 1: + return G; + default: + return B; + } + } + // ------------------------------------------------------------------------ // CalculateBrightness will calculate the overall brightness // NOTE: This is a simple linear brightness @@ -151,7 +212,11 @@ struct Rgb48Color : RgbColorBase // and a value between will blend the color weighted linearly between them // ------------------------------------------------------------------------ static Rgb48Color LinearBlend(const Rgb48Color& left, const Rgb48Color& right, float progress); - + // progress - (0 - 255) value where 0 will return left and 255 will return right + // and a value between will blend the color weighted linearly between them + // ------------------------------------------------------------------------ + static Rgb48Color LinearBlend(const Rgb48Color& left, const Rgb48Color& right, uint8_t progress); + // ------------------------------------------------------------------------ // BilinearBlend between four colors by the amount defined by 2d variable // c00 - upper left quadrant color @@ -188,6 +253,7 @@ struct Rgb48Color : RgbColorBase uint16_t B; const static uint16_t Max = 65535; + const static size_t Count = 3; // three elements in [] private: inline static uint16_t _elementDim(uint16_t value, uint16_t ratio) diff --git a/src/internal/RgbColor.cpp b/src/internal/RgbColor.cpp index 560d2b7..5a6f1d8 100644 --- a/src/internal/RgbColor.cpp +++ b/src/internal/RgbColor.cpp @@ -24,6 +24,7 @@ License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ +#include #include "RgbColor.h" #include "Rgb16Color.h" #include "Rgb48Color.h" @@ -162,9 +163,16 @@ void RgbColor::Lighten(uint8_t delta) RgbColor RgbColor::LinearBlend(const RgbColor& left, const RgbColor& right, float progress) { - return RgbColor( left.R + (((int16_t)right.R - left.R) * progress), - left.G + (((int16_t)right.G - left.G) * progress), - left.B + (((int16_t)right.B - left.B) * progress)); + return RgbColor( left.R + ((static_cast(right.R) - left.R) * progress), + left.G + ((static_cast(right.G) - left.G) * progress), + left.B + ((static_cast(right.B) - left.B) * progress)); +} + +RgbColor RgbColor::LinearBlend(const RgbColor& left, const RgbColor& right, uint8_t progress) +{ + return RgbColor(left.R + (((static_cast(right.R) - left.R) * static_cast(progress) + 1) >> 8), + left.G + (((static_cast(right.G) - left.G) * static_cast(progress) + 1) >> 8), + left.B + (((static_cast(right.B) - left.B) * static_cast(progress) + 1) >> 8)); } RgbColor RgbColor::BilinearBlend(const RgbColor& c00, diff --git a/src/internal/RgbColor.h b/src/internal/RgbColor.h index aa999f5..d116c62 100644 --- a/src/internal/RgbColor.h +++ b/src/internal/RgbColor.h @@ -25,7 +25,6 @@ License along with NeoPixel. If not, see -------------------------------------------------------------------------*/ #pragma once -#include #include "NeoSettings.h" #include "RgbColorBase.h" @@ -105,6 +104,68 @@ struct RgbColor : RgbColorBase return !(*this == other); }; + // ------------------------------------------------------------------------ + // CompareTo method + // compares against another color with the given epsilon (delta allowed) + // returns the greatest difference of a set of elements, + // 0 = equal within epsilon delta + // negative - this is less than other + // positive - this is greater than other + // ------------------------------------------------------------------------ + int16_t CompareTo(const RgbColor& other, uint8_t epsilon = 1) + { + return _Compare(*this, other, epsilon); + } + + // ------------------------------------------------------------------------ + // Compare method + // compares two colors with the given epsilon (delta allowed) + // returns the greatest difference of a set of elements, + // 0 = equal within epsilon delta + // negative - this is less than other + // positive - this is greater than other + // ------------------------------------------------------------------------ + static int16_t Compare(const RgbColor& left, const RgbColor& right, uint8_t epsilon = 1) + { + return _Compare(left, right, epsilon); + } + + // ------------------------------------------------------------------------ + // operator [] - readonly + // access elements in order by index rather than R,G,B + // see static Count for the number of elements + // ------------------------------------------------------------------------ + uint8_t operator[](size_t idx) const + { + switch (idx) + { + case 0: + return R; + case 1: + return G; + default: + return B; + } + } + + // ------------------------------------------------------------------------ + // operator [] - read write + // access elements in order by index rather than R,G,B + // see static Count for the number of elements + // ------------------------------------------------------------------------ + uint8_t& operator[](size_t idx) + { + switch (idx) + { + case 0: + return R; + case 1: + return G; + default: + return B; + } + } + // ------------------------------------------------------------------------ // CalculateBrightness will calculate the overall brightness // NOTE: This is a simple linear brightness @@ -149,7 +210,11 @@ struct RgbColor : RgbColorBase // and a value between will blend the color weighted linearly between them // ------------------------------------------------------------------------ static RgbColor LinearBlend(const RgbColor& left, const RgbColor& right, float progress); - + // progress - (0 - 255) value where 0 will return left and 255 will return right + // and a value between will blend the color weighted linearly between them + // ------------------------------------------------------------------------ + static RgbColor LinearBlend(const RgbColor& left, const RgbColor& right, uint8_t progress); + // ------------------------------------------------------------------------ // BilinearBlend between four colors by the amount defined by 2d variable // c00 - upper left quadrant color @@ -186,6 +251,7 @@ struct RgbColor : RgbColorBase uint8_t B; const static uint8_t Max = 255; + const static size_t Count = 3; // three elements in [] private: inline static uint8_t _elementDim(uint8_t value, uint8_t ratio) diff --git a/src/internal/RgbColorBase.cpp b/src/internal/RgbColorBase.cpp index ad0eb82..7938915 100644 --- a/src/internal/RgbColorBase.cpp +++ b/src/internal/RgbColorBase.cpp @@ -24,6 +24,7 @@ License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ +#include #include "RgbColorBase.h" #include "RgbColor.h" #include "Rgb48Color.h" diff --git a/src/internal/RgbColorBase.h b/src/internal/RgbColorBase.h index 689fe88..aef9d9a 100644 --- a/src/internal/RgbColorBase.h +++ b/src/internal/RgbColorBase.h @@ -39,4 +39,31 @@ protected: static void _HslToRgb(const HslColor& color, float* r, float* g, float* b); static void _HsbToRgb(const HsbColor& color, float* r, float* g, float* b); + + template static T_RESULT _Compare( + const T_COLOR& left, + const T_COLOR& right, + T_RESULT epsilon) + { + T_RESULT result = 0; + T_RESULT resultAbs = 0; + + for (size_t elem = 0; elem < T_COLOR::Count; elem++) + { + T_RESULT delta = static_cast(left[elem]) - right[elem]; + T_RESULT deltaAbs = abs(delta); + + if (deltaAbs > resultAbs) + { + resultAbs = deltaAbs; + result = delta; + } + } + + if (resultAbs > epsilon) + { + return result; + } + return 0; + } }; \ No newline at end of file diff --git a/src/internal/Rgbw64Color.cpp b/src/internal/Rgbw64Color.cpp index a84077c..7987158 100644 --- a/src/internal/Rgbw64Color.cpp +++ b/src/internal/Rgbw64Color.cpp @@ -24,6 +24,7 @@ License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ +#include #include "RgbColor.h" #include "RgbwColor.h" #include "Rgb48Color.h" @@ -162,10 +163,17 @@ void Rgbw64Color::Lighten(uint16_t delta) Rgbw64Color Rgbw64Color::LinearBlend(const Rgbw64Color& left, const Rgbw64Color& right, float progress) { - return Rgbw64Color( left.R + (((int32_t)right.R - left.R) * progress), - left.G + (((int32_t)right.G - left.G) * progress), - left.B + (((int32_t)right.B - left.B) * progress), - left.W + (((int32_t)right.W - left.W) * progress) ); + return Rgbw64Color( left.R + ((static_cast(right.R) - left.R) * progress), + left.G + ((static_cast(right.G) - left.G) * progress), + left.B + ((static_cast(right.B) - left.B) * progress), + left.W + ((static_cast(right.W) - left.W) * progress) ); +} +Rgbw64Color Rgbw64Color::LinearBlend(const Rgbw64Color& left, const Rgbw64Color& right, uint8_t progress) +{ + return Rgbw64Color(left.R + (((static_cast(right.R) - left.R) * static_cast(progress) + 1) >> 8), + left.G + (((static_cast(right.G) - left.G) * static_cast(progress) + 1) >> 8), + left.B + (((static_cast(right.B) - left.B) * static_cast(progress) + 1) >> 8), + left.W + (((static_cast(right.W) - left.W) * static_cast(progress) + 1) >> 8)); } Rgbw64Color Rgbw64Color::BilinearBlend(const Rgbw64Color& c00, diff --git a/src/internal/Rgbw64Color.h b/src/internal/Rgbw64Color.h index 218282a..920ec25 100644 --- a/src/internal/Rgbw64Color.h +++ b/src/internal/Rgbw64Color.h @@ -25,7 +25,6 @@ License along with NeoPixel. If not, see -------------------------------------------------------------------------*/ #pragma once -#include #include "NeoSettings.h" struct RgbColor; @@ -37,7 +36,7 @@ struct HsbColor; // component values and an extra White component. It contains helpful color // routines to manipulate the color. // ------------------------------------------------------------------------ -struct Rgbw64Color +struct Rgbw64Color : RgbColorBase { typedef NeoRgbwCurrentSettings SettingsObject; @@ -122,6 +121,72 @@ struct Rgbw64Color return !(*this == other); }; + // ------------------------------------------------------------------------ + // CompareTo method + // compares against another color with the given epsilon (delta allowed) + // returns the greatest difference of a set of elements, + // 0 = equal within epsilon delta + // negative - this is less than other + // positive - this is greater than other + // ------------------------------------------------------------------------ + int32_t CompareTo(const Rgbw64Color& other, uint16_t epsilon = 256) + { + return _Compare(*this, other, epsilon); + } + + // ------------------------------------------------------------------------ + // Compare method + // compares two colors with the given epsilon (delta allowed) + // returns the greatest difference of a set of elements, + // 0 = equal within epsilon delta + // negative - this is less than other + // positive - this is greater than other + // ------------------------------------------------------------------------ + static int32_t Compare(const Rgbw64Color& left, const Rgbw64Color& right, uint16_t epsilon = 256) + { + return _Compare(left, right, epsilon); + } + + // ------------------------------------------------------------------------ + // operator [] - readonly + // access elements in order by index rather than R,G,B + // see static Count for the number of elements + // ------------------------------------------------------------------------ + uint16_t operator[](size_t idx) const + { + switch (idx) + { + case 0: + return R; + case 1: + return G; + case 2: + return B; + default: + return W; + } + } + + // ------------------------------------------------------------------------ + // operator [] - read write + // access elements in order by index rather than R,G,B + // see static Count for the number of elements + // ------------------------------------------------------------------------ + uint16_t& operator[](size_t idx) + { + switch (idx) + { + case 0: + return R; + case 1: + return G; + case 2: + return B; + default: + return W; + } + } + // ------------------------------------------------------------------------ // Returns if the color is grey, all values are equal other than white // ------------------------------------------------------------------------ @@ -183,7 +248,11 @@ struct Rgbw64Color // and a value between will blend the color weighted linearly between them // ------------------------------------------------------------------------ static Rgbw64Color LinearBlend(const Rgbw64Color& left, const Rgbw64Color& right, float progress); - + // progress - (0 - 255) value where 0 will return left and 255 will return right + // and a value between will blend the color weighted linearly between them + // ------------------------------------------------------------------------ + static Rgbw64Color LinearBlend(const Rgbw64Color& left, const Rgbw64Color& right, uint8_t progress); + // ------------------------------------------------------------------------ // BilinearBlend between four colors by the amount defined by 2d variable // c00 - upper left quadrant color @@ -223,6 +292,7 @@ struct Rgbw64Color uint16_t W; const static uint16_t Max = 65535; + const static size_t Count = 4; // four elements in [] private: inline static uint16_t _elementDim(uint16_t value, uint16_t ratio) diff --git a/src/internal/RgbwColor.cpp b/src/internal/RgbwColor.cpp index b11997b..ba67877 100644 --- a/src/internal/RgbwColor.cpp +++ b/src/internal/RgbwColor.cpp @@ -24,6 +24,7 @@ License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ +#include #include "RgbColor.h" #include "Rgb48Color.h" #include "HslColor.h" @@ -165,10 +166,17 @@ void RgbwColor::Lighten(uint8_t delta) RgbwColor RgbwColor::LinearBlend(const RgbwColor& left, const RgbwColor& right, float progress) { - return RgbwColor( left.R + (((int16_t)right.R - left.R) * progress), - left.G + (((int16_t)right.G - left.G) * progress), - left.B + (((int16_t)right.B - left.B) * progress), - left.W + (((int16_t)right.W - left.W) * progress) ); + return RgbwColor( left.R + ((static_cast(right.R) - left.R) * progress), + left.G + ((static_cast(right.G) - left.G) * progress), + left.B + ((static_cast(right.B) - left.B) * progress), + left.W + ((static_cast(right.W) - left.W) * progress) ); +} +RgbwColor RgbwColor::LinearBlend(const RgbwColor& left, const RgbwColor& right, uint8_t progress) +{ + return RgbwColor(left.R + (((static_cast(right.R) - left.R) * static_cast(progress) + 1) >> 8), + left.G + (((static_cast(right.G) - left.G) * static_cast(progress) + 1) >> 8), + left.B + (((static_cast(right.B) - left.B) * static_cast(progress) + 1) >> 8), + left.W + (((static_cast(right.W) - left.W) * static_cast(progress) + 1) >> 8)); } RgbwColor RgbwColor::BilinearBlend(const RgbwColor& c00, diff --git a/src/internal/RgbwColor.h b/src/internal/RgbwColor.h index 2bc7b70..aacebac 100644 --- a/src/internal/RgbwColor.h +++ b/src/internal/RgbwColor.h @@ -25,8 +25,6 @@ License along with NeoPixel. If not, see -------------------------------------------------------------------------*/ #pragma once -#include - struct RgbColor; struct HslColor; struct HsbColor; @@ -36,7 +34,7 @@ struct HsbColor; // component values and an extra White component. It contains helpful color // routines to manipulate the color. // ------------------------------------------------------------------------ -struct RgbwColor +struct RgbwColor : RgbColorBase { typedef NeoRgbwCurrentSettings SettingsObject; @@ -105,6 +103,72 @@ struct RgbwColor return !(*this == other); }; + // ------------------------------------------------------------------------ + // CompareTo method + // compares against another color with the given epsilon (delta allowed) + // returns the greatest difference of a set of elements, + // 0 = equal within epsilon delta + // negative - this is less than other + // positive - this is greater than other + // ------------------------------------------------------------------------ + int16_t CompareTo(const RgbwColor& other, uint8_t epsilon = 1) + { + return _Compare(*this, other, epsilon); + } + + // ------------------------------------------------------------------------ + // Compare method + // compares two colors with the given epsilon (delta allowed) + // returns the greatest difference of a set of elements, + // 0 = equal within epsilon delta + // negative - this is less than other + // positive - this is greater than other + // ------------------------------------------------------------------------ + static int16_t Compare(const RgbwColor& left, const RgbwColor& right, uint8_t epsilon = 1) + { + return _Compare(left, right, epsilon); + } + + // ------------------------------------------------------------------------ + // operator [] - readonly + // access elements in order by index rather than R,G,B + // see static Count for the number of elements + // ------------------------------------------------------------------------ + uint8_t operator[](size_t idx) const + { + switch (idx) + { + case 0: + return R; + case 1: + return G; + case 2: + return B; + default: + return W; + } + } + + // ------------------------------------------------------------------------ + // operator [] - read write + // access elements in order by index rather than R,G,B + // see static Count for the number of elements + // ------------------------------------------------------------------------ + uint8_t& operator[](size_t idx) + { + switch (idx) + { + case 0: + return R; + case 1: + return G; + case 2: + return B; + default: + return W; + } + } + // ------------------------------------------------------------------------ // Returns if the color is grey, all values are equal other than white // ------------------------------------------------------------------------ @@ -166,7 +230,11 @@ struct RgbwColor // and a value between will blend the color weighted linearly between them // ------------------------------------------------------------------------ static RgbwColor LinearBlend(const RgbwColor& left, const RgbwColor& right, float progress); - + // progress - (0 - 255) value where 0 will return left and 255 will return right + // and a value between will blend the color weighted linearly between them + // ------------------------------------------------------------------------ + static RgbwColor LinearBlend(const RgbwColor& left, const RgbwColor& right, uint8_t progress); + // ------------------------------------------------------------------------ // BilinearBlend between four colors by the amount defined by 2d variable // c00 - upper left quadrant color @@ -206,6 +274,7 @@ struct RgbwColor uint8_t W; const static uint8_t Max = 255; + const static size_t Count = 4; // four elements in [] private: inline static uint8_t _elementDim(uint8_t value, uint8_t ratio) diff --git a/src/internal/SegmentDigit.cpp b/src/internal/SegmentDigit.cpp index 7b2cfd9..a04af91 100644 --- a/src/internal/SegmentDigit.cpp +++ b/src/internal/SegmentDigit.cpp @@ -24,6 +24,7 @@ License along with NeoPixel. If not, see . -------------------------------------------------------------------------*/ +#include #include "SegmentDigit.h" // @@ -59,7 +60,7 @@ const uint8_t SevenSegDigit::DecodeSpecial[] = { void SevenSegDigit::init(uint8_t bitmask, uint8_t brightness, uint8_t defaultBrightness) { - for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++) + for (uint8_t iSegment = 0; iSegment < Count; iSegment++) { Segment[iSegment] = (bitmask & 0x01) ? brightness : defaultBrightness; bitmask >>= 1; @@ -111,17 +112,17 @@ uint8_t SevenSegDigit::CalculateBrightness() const { uint16_t sum = 0; - for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++) + for (uint8_t iSegment = 0; iSegment < Count; iSegment++) { sum += Segment[iSegment]; } - return static_cast(sum / SegmentCount); + return static_cast(sum / Count); } void SevenSegDigit::Darken(uint8_t delta) { - for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++) + for (uint8_t iSegment = 0; iSegment < Count; iSegment++) { uint8_t element = Segment[iSegment]; if (element > delta) @@ -138,7 +139,7 @@ void SevenSegDigit::Darken(uint8_t delta) void SevenSegDigit::Lighten(uint8_t delta) { - for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++) + for (uint8_t iSegment = 0; iSegment < Count; iSegment++) { uint8_t element = Segment[iSegment]; if (element < 255 - delta) @@ -157,9 +158,22 @@ SevenSegDigit SevenSegDigit::LinearBlend(const SevenSegDigit& left, const SevenS { SevenSegDigit result; - for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++) + for (uint8_t iSegment = 0; iSegment < Count; iSegment++) { - result.Segment[iSegment] = left.Segment[iSegment] + (((int16_t)right.Segment[iSegment] - left.Segment[iSegment]) * progress); + result.Segment[iSegment] = left.Segment[iSegment] + ((static_cast(right.Segment[iSegment]) - left.Segment[iSegment]) * progress); } return result; } + +SevenSegDigit SevenSegDigit::LinearBlend(const SevenSegDigit& left, const SevenSegDigit& right, uint8_t progress) +{ + SevenSegDigit result; + + for (uint8_t iSegment = 0; iSegment < Count; iSegment++) + { + result.Segment[iSegment] = left.Segment[iSegment] + + (((static_cast(right.Segment[iSegment]) - left.Segment[iSegment]) * static_cast(progress) + 1) >> 8); + } + return result; +} + diff --git a/src/internal/SegmentDigit.h b/src/internal/SegmentDigit.h index a7fe452..19d3930 100644 --- a/src/internal/SegmentDigit.h +++ b/src/internal/SegmentDigit.h @@ -25,8 +25,6 @@ License along with NeoPixel. If not, see -------------------------------------------------------------------------*/ #pragma once -#include - enum LedSegment { LedSegment_A, @@ -107,7 +105,7 @@ struct SevenSegDigit // ------------------------------------------------------------------------ bool operator==(const SevenSegDigit& other) const { - for (uint8_t iSegment = 0; iSegment < SegmentCount; iSegment++) + for (uint8_t iSegment = 0; iSegment < Count; iSegment++) { if (Segment[iSegment] != other.Segment[iSegment]) { @@ -122,6 +120,26 @@ struct SevenSegDigit return !(*this == other); }; + // ------------------------------------------------------------------------ + // operator [] - readonly + // access elements in order of the Segments + // see static Count for the number of elements + // ------------------------------------------------------------------------ + uint8_t operator[](size_t idx) const + { + return Segment[idx]; + } + + // ------------------------------------------------------------------------ + // operator [] - read write + // access elements in order by index rather than R,G,B + // see static Count for the number of elements + // ------------------------------------------------------------------------ + uint8_t& operator[](size_t idx) + { + return Segment[idx]; + } + // ------------------------------------------------------------------------ // CalculateBrightness will calculate the overall brightness // NOTE: This is a simple linear brightness @@ -151,19 +169,23 @@ struct SevenSegDigit // weighted linearly between them // ------------------------------------------------------------------------ static SevenSegDigit LinearBlend(const SevenSegDigit& left, const SevenSegDigit& right, float progress); + // progress - (0 - 255) value where 0 will return left and 255 will return right + // and a value between will blend the color weighted linearly between them + // ------------------------------------------------------------------------ + static SevenSegDigit LinearBlend(const SevenSegDigit& left, const SevenSegDigit& right, uint8_t progress); uint32_t CalcTotalTenthMilliAmpere(const SettingsObject& settings) { auto total = 0; - for (uint8_t segment = LedSegment_A; segment < SegmentCount - 2; segment++) + for (uint8_t segment = LedSegment_A; segment < Count - 2; segment++) { total += Segment[segment] * settings.SegmentTenthMilliAmpere / Max; } - total += Segment[SegmentCount - 2] * settings.DecimalTenthMilliAmpere / Max; - total += Segment[SegmentCount - 1] * settings.SpecialTenthMilliAmpere / Max; + total += Segment[Count - 2] * settings.DecimalTenthMilliAmpere / Max; + total += Segment[Count - 1] * settings.SpecialTenthMilliAmpere / Max; return total; } @@ -249,8 +271,8 @@ struct SevenSegDigit // segment members (0-255) where each represents the segment location // and the value defines the brightnes (0) is off and (255) is full brightness // ------------------------------------------------------------------------ - static const uint8_t SegmentCount = 9; - uint8_t Segment[SegmentCount]; + static const uint8_t Count = 9; + uint8_t Segment[Count]; const static uint8_t Max = 255;