diff --git a/examples/NeoPixelGamma/NeoPixelGamma.ino b/examples/NeoPixelGamma/NeoPixelGamma.ino index 3621f489..a0487c08 100644 --- a/examples/NeoPixelGamma/NeoPixelGamma.ino +++ b/examples/NeoPixelGamma/NeoPixelGamma.ino @@ -27,7 +27,7 @@ void DrawPixels(bool corrected, HslColor startColor, HslColor stopColor) for (uint16_t index = 0; index < strip.PixelCount() - 1; index++) { float progress = index / static_cast(strip.PixelCount() - 2); - RgbColor color = HslColor::LinearBlend(startColor, stopColor, progress); + RgbColor color = HslColor::LinearBlend(startColor, stopColor, progress); if (corrected) { color = colorGamma.Correct(color); diff --git a/keywords.txt b/keywords.txt index 30b15006..b8f22da0 100644 --- a/keywords.txt +++ b/keywords.txt @@ -53,6 +53,10 @@ NeoMosaic KEYWORD1 NeoGammaEquationMethod KEYWORD1 NeoGammaTableMethod KEYWORD1 NeoGamma KEYWORD1 +NeoHueBlendShortestDistance KEYWORD1 +NeoHueBlendLongestDistance KEYWORD1 +NeoHueBlendClockwiseDirection KEYWORD1 +NeoHueBlendCounterClockwiseDirection KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) diff --git a/library.properties b/library.properties index 4bcae0bc..4d764968 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=NeoPixelBus by Makuna -version=2.0.4 +version=2.0.5 author=Michael C. Miller (makuna@live.com) maintainer=Michael C. Miller (makuna@live.com) sentence=A library that makes controlling NeoPixels (WS2811, WS2812 & SK6812) easy. -paragraph=Supports most Arduino platforms, and especially Esp8266. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. For Esp8266 it has three methods of sending data, DMA, UART, and Bit Bang. +paragraph=Supports most Arduino platforms, and especially Esp8266. Support for RGBW pixels. Includes seperate RgbColor, RgbwColor, HslColor, and HsbColor objects. Includes an animator class that helps create asyncronous animations. Supports Matrix layout of pixels. Includes Gamma corretion object. For Esp8266 it has three methods of sending data, DMA, UART, and Bit Bang. category=Display url=https://github.com/Makuna/NeoPixelBus/wiki architectures=* \ No newline at end of file diff --git a/src/NeoPixelBus.h b/src/NeoPixelBus.h index 8b2c326e..44458cd1 100644 --- a/src/NeoPixelBus.h +++ b/src/NeoPixelBus.h @@ -27,6 +27,8 @@ License along with NeoPixel. If not, see #include +#include "internal/NeoHueBlend.h" + #include "internal/RgbColor.h" #include "internal/HslColor.h" #include "internal/HsbColor.h" diff --git a/src/internal/HsbColor.cpp b/src/internal/HsbColor.cpp index 31f1b325..e47912fa 100644 --- a/src/internal/HsbColor.cpp +++ b/src/internal/HsbColor.cpp @@ -66,10 +66,3 @@ HsbColor::HsbColor(const RgbColor& color) S = s; B = v; } - -HsbColor HsbColor::LinearBlend(const HsbColor& left, const HsbColor& right, float progress) -{ - return HsbColor(left.H + ((right.H - left.H) * progress), - left.S + ((right.S - left.S) * progress), - left.B + ((right.B - left.B) * progress)); -} \ No newline at end of file diff --git a/src/internal/HsbColor.h b/src/internal/HsbColor.h index ef1639c4..324195a0 100644 --- a/src/internal/HsbColor.h +++ b/src/internal/HsbColor.h @@ -63,7 +63,14 @@ struct HsbColor // progress - (0.0 - 1.0) value where 0.0 will return left and 1.0 will return right // and a value between will blend the color weighted linearly between them // ------------------------------------------------------------------------ - static HsbColor LinearBlend(const HsbColor& left, const HsbColor& right, float progress); + template static HsbColor LinearBlend(const HsbColor& left, + const HsbColor& right, + float progress) + { + return HsbColor(T_NEOHUEBLEND::HueBlend(left.H, right.H, progress), + left.S + ((right.S - left.S) * progress), + left.B + ((right.B - left.B) * progress)); + } // ------------------------------------------------------------------------ // Hue, Saturation, Brightness color members diff --git a/src/internal/HslColor.cpp b/src/internal/HslColor.cpp index 59c418de..ce9b2388 100644 --- a/src/internal/HslColor.cpp +++ b/src/internal/HslColor.cpp @@ -70,10 +70,3 @@ HslColor::HslColor(const RgbColor& color) S = s; L = l; } - -HslColor HslColor::LinearBlend(const HslColor& left, const HslColor& right, float progress) -{ - return HslColor(left.H + ((right.H - left.H) * progress), - left.S + ((right.S - left.S) * progress), - left.L + ((right.L - left.L) * progress)); -} \ No newline at end of file diff --git a/src/internal/HslColor.h b/src/internal/HslColor.h index 6b41d540..45fb738b 100644 --- a/src/internal/HslColor.h +++ b/src/internal/HslColor.h @@ -64,7 +64,14 @@ struct HslColor // progress - (0.0 - 1.0) value where 0.0 will return left and 1.0 will return right // and a value between will blend the color weighted linearly between them // ------------------------------------------------------------------------ - static HslColor LinearBlend(const HslColor& left, const HslColor& right, float progress); + template static HslColor LinearBlend(const HslColor& left, + const HslColor& right, + float progress) + { + return HslColor(T_NEOHUEBLEND::HueBlend(left.H, right.H, progress), + left.S + ((right.S - left.S) * progress), + left.L + ((right.L - left.L) * progress)); + }; // ------------------------------------------------------------------------ // Hue, Saturation, Lightness color members diff --git a/src/internal/NeoHueBlend.h b/src/internal/NeoHueBlend.h new file mode 100644 index 00000000..d77a58fb --- /dev/null +++ b/src/internal/NeoHueBlend.h @@ -0,0 +1,118 @@ +/*------------------------------------------------------------------------- +NeoHueBlend provides method objects that can be directly consumed by +blend template functions in HslColor and HsbColor + +Written by Michael C. Miller. + +I invest time and resources providing this open source code, +please support me by dontating (see https://github.com/Makuna/NeoPixelBus) + +------------------------------------------------------------------------- +This file is part of the Makuna/NeoPixelBus library. + +NeoPixelBus is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as +published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +NeoPixelBus is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with NeoPixel. If not, see +. +-------------------------------------------------------------------------*/ +#pragma once + +class NeoHueBlendBase +{ +protected: + static float FixWrap(float value) + { + if (value < 0.0f) + { + value += 1.0f; + } + else if (value > 1.0f) + { + value -= 1.0f; + } + return value; + } +}; + +class NeoHueBlendShortestDistance : NeoHueBlendBase +{ +public: + static float HueBlend(float left, float right, float progress) + { + float delta = right - left; + float base = left; + if (delta > 0.5f) + { + base = right; + delta = 1.0f - delta; + progress = 1.0f - progress; + } + else if (delta < -0.5f) + { + delta = 1.0f + delta; + } + return FixWrap(base + (delta) * progress); + }; +}; + +class NeoHueBlendLongestDistance : NeoHueBlendBase +{ +public: + static float HueBlend(float left, float right, float progress) + { + float delta = right - left; + float base = left; + if (delta < 0.5f && delta >= 0.0f) + { + base = right; + delta = 1.0f - delta; + progress = 1.0f - progress; + } + else if (delta > -0.5f && delta < 0.0f) + { + delta = 1.0f + delta; + } + return FixWrap(base + delta * progress); + }; +}; + +class NeoHueBlendClockwiseDirection : NeoHueBlendBase +{ +public: + static float HueBlend(float left, float right, float progress) + { + float delta = right - left; + float base = left; + if (delta < 0.0f) + { + delta = 1.0f + delta; + } + + return FixWrap(base + delta * progress); + }; +}; + +class NeoHueBlendCounterClockwiseDirection : NeoHueBlendBase +{ +public: + static float HueBlend(float left, float right, float progress) + { + float delta = right - left; + float base = left; + if (delta > 0.0f) + { + delta = delta - 1.0f; + } + + return FixWrap(base + delta * progress); + }; +};