Hue Blend Direction support

This commit is contained in:
Makuna
2016-03-28 12:21:11 -07:00
parent 2c07835340
commit d351014ac8
9 changed files with 143 additions and 19 deletions

View File

@@ -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<float>(strip.PixelCount() - 2);
RgbColor color = HslColor::LinearBlend(startColor, stopColor, progress);
RgbColor color = HslColor::LinearBlend<NeoHueBlendShortestDistance>(startColor, stopColor, progress);
if (corrected)
{
color = colorGamma.Correct(color);

View File

@@ -53,6 +53,10 @@ NeoMosaic KEYWORD1
NeoGammaEquationMethod KEYWORD1
NeoGammaTableMethod KEYWORD1
NeoGamma KEYWORD1
NeoHueBlendShortestDistance KEYWORD1
NeoHueBlendLongestDistance KEYWORD1
NeoHueBlendClockwiseDirection KEYWORD1
NeoHueBlendCounterClockwiseDirection KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)

View File

@@ -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=*

View File

@@ -27,6 +27,8 @@ License along with NeoPixel. If not, see
#include <Arduino.h>
#include "internal/NeoHueBlend.h"
#include "internal/RgbColor.h"
#include "internal/HslColor.h"
#include "internal/HsbColor.h"

View File

@@ -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));
}

View File

@@ -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 <typename T_NEOHUEBLEND> 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

View File

@@ -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));
}

View File

@@ -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 <typename T_NEOHUEBLEND> 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

118
src/internal/NeoHueBlend.h Normal file
View File

@@ -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
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#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);
};
};