Linear blend uint8 (#650)

LinearBlend using uint8_t
index accessors to color elements
standardized Count for index accessor length
compare feature
fixed ardunio.h include
This commit is contained in:
Michael Miller
2023-02-11 18:29:46 -08:00
committed by GitHub
parent 7e38508ec8
commit 656a48ff33
26 changed files with 425 additions and 56 deletions

View File

@@ -24,6 +24,7 @@ License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include <Arduino.h>
#include "RgbColor.h"
#include "Rgb48Color.h"
#include "HsbColor.h"

View File

@@ -26,8 +26,6 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
// ------------------------------------------------------------------------
// HsbColor represents a color object that is represented by Hue, Saturation, Brightness
// component values. It contains helpful color routines to manipulate the

View File

@@ -25,6 +25,7 @@ License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include <Arduino.h>
#include "RgbColor.h"
#include "Rgb48Color.h"
#include "HslColor.h"

View File

@@ -25,8 +25,6 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
// ------------------------------------------------------------------------
// HslColor represents a color object that is represented by Hue, Saturation, Lightness
// component values. It contains helpful color routines to manipulate the

View File

@@ -23,6 +23,8 @@ You should have received a copy of the GNU Lesser General Public
License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include <Arduino.h>
#include "HtmlColor.h"
static inline char hexdigit(uint8_t v)

View File

@@ -24,6 +24,7 @@ License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include <Arduino.h>
#include "HtmlColorNameStrings.h"
/* HTML4 color names */

View File

@@ -26,8 +26,6 @@ License along with NeoPixel. If not, see
#pragma once
#include <Arduino.h>
/* HTML4 color names */
extern const char c_HtmlNameAqua[] PROGMEM;
extern const char c_HtmlNameBlack[] PROGMEM;

View File

@@ -32,7 +32,6 @@ License along with NeoPixel. If not, see
extern "C"
{
#include <Arduino.h>
#include "Esp32_i2s.h"
}

View File

@@ -31,7 +31,6 @@ License along with NeoPixel. If not, see
extern "C"
{
#include <Arduino.h>
#include "Esp32_i2s.h"
}

View File

@@ -43,8 +43,6 @@ Esp32-hal-rmt.h
Esp32-hal-rmt.c
*/
#include <Arduino.h>
extern "C"
{
#include <driver/rmt.h>

View File

@@ -27,7 +27,6 @@ License along with NeoPixel. If not, see
#pragma once
#ifdef ARDUINO_ARCH_ESP8266
#include <Arduino.h>
// 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

View File

@@ -24,6 +24,7 @@ License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include <Arduino.h>
#include "NeoPixelBus.h"
#include "NeoPixelAnimator.h"

View File

@@ -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++)
{

View File

@@ -25,7 +25,6 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
#include "NeoSettings.h"
#include "RgbColorBase.h"
@@ -243,6 +242,15 @@ 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

View File

@@ -24,6 +24,7 @@ License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include <Arduino.h>
#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<int32_t>(right.R) - left.R) * progress),
left.G + ((static_cast<int32_t>(right.G) - left.G) * progress),
left.B + ((static_cast<int32_t>(right.B) - left.B) * progress));
}
Rgb48Color Rgb48Color::LinearBlend(const Rgb48Color& left, const Rgb48Color& right, uint8_t progress)
{
return Rgb48Color(left.R + (((static_cast<int64_t>(right.R) - left.R) * static_cast<int64_t>(progress) + 1) >> 8),
left.G + (((static_cast<int64_t>(right.G) - left.G) * static_cast<int64_t>(progress) + 1) >> 8),
left.B + (((static_cast<int64_t>(right.B) - left.B) * static_cast<int64_t>(progress) + 1) >> 8));
}
Rgb48Color Rgb48Color::BilinearBlend(const Rgb48Color& c00,

View File

@@ -25,7 +25,6 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
#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<Rgb48Color, int32_t>(*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<Rgb48Color, int32_t>(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,6 +212,10 @@ 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
@@ -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)

View File

@@ -24,6 +24,7 @@ License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include <Arduino.h>
#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<int16_t>(right.R) - left.R) * progress),
left.G + ((static_cast<int16_t>(right.G) - left.G) * progress),
left.B + ((static_cast<int16_t>(right.B) - left.B) * progress));
}
RgbColor RgbColor::LinearBlend(const RgbColor& left, const RgbColor& right, uint8_t progress)
{
return RgbColor(left.R + (((static_cast<int32_t>(right.R) - left.R) * static_cast<int32_t>(progress) + 1) >> 8),
left.G + (((static_cast<int32_t>(right.G) - left.G) * static_cast<int32_t>(progress) + 1) >> 8),
left.B + (((static_cast<int32_t>(right.B) - left.B) * static_cast<int32_t>(progress) + 1) >> 8));
}
RgbColor RgbColor::BilinearBlend(const RgbColor& c00,

View File

@@ -25,7 +25,6 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
#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<RgbColor, int16_t>(*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<RgbColor, int16_t>(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,6 +210,10 @@ 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
@@ -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)

View File

@@ -24,6 +24,7 @@ License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include <Arduino.h>
#include "RgbColorBase.h"
#include "RgbColor.h"
#include "Rgb48Color.h"

View File

@@ -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 <typename T_COLOR, typename T_RESULT> 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<T_RESULT>(left[elem]) - right[elem];
T_RESULT deltaAbs = abs(delta);
if (deltaAbs > resultAbs)
{
resultAbs = deltaAbs;
result = delta;
}
}
if (resultAbs > epsilon)
{
return result;
}
return 0;
}
};

View File

@@ -24,6 +24,7 @@ License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include <Arduino.h>
#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<int32_t>(right.R) - left.R) * progress),
left.G + ((static_cast<int32_t>(right.G) - left.G) * progress),
left.B + ((static_cast<int32_t>(right.B) - left.B) * progress),
left.W + ((static_cast<int32_t>(right.W) - left.W) * progress) );
}
Rgbw64Color Rgbw64Color::LinearBlend(const Rgbw64Color& left, const Rgbw64Color& right, uint8_t progress)
{
return Rgbw64Color(left.R + (((static_cast<int64_t>(right.R) - left.R) * static_cast<int64_t>(progress) + 1) >> 8),
left.G + (((static_cast<int64_t>(right.G) - left.G) * static_cast<int64_t>(progress) + 1) >> 8),
left.B + (((static_cast<int64_t>(right.B) - left.B) * static_cast<int64_t>(progress) + 1) >> 8),
left.W + (((static_cast<int64_t>(right.W) - left.W) * static_cast<int64_t>(progress) + 1) >> 8));
}
Rgbw64Color Rgbw64Color::BilinearBlend(const Rgbw64Color& c00,

View File

@@ -25,7 +25,6 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
#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<Rgbw64Color, int32_t>(*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<Rgbw64Color, int32_t>(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,6 +248,10 @@ 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
@@ -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)

View File

@@ -24,6 +24,7 @@ License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include <Arduino.h>
#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<int16_t>(right.R) - left.R) * progress),
left.G + ((static_cast<int16_t>(right.G) - left.G) * progress),
left.B + ((static_cast<int16_t>(right.B) - left.B) * progress),
left.W + ((static_cast<int16_t>(right.W) - left.W) * progress) );
}
RgbwColor RgbwColor::LinearBlend(const RgbwColor& left, const RgbwColor& right, uint8_t progress)
{
return RgbwColor(left.R + (((static_cast<int32_t>(right.R) - left.R) * static_cast<int32_t>(progress) + 1) >> 8),
left.G + (((static_cast<int32_t>(right.G) - left.G) * static_cast<int32_t>(progress) + 1) >> 8),
left.B + (((static_cast<int32_t>(right.B) - left.B) * static_cast<int32_t>(progress) + 1) >> 8),
left.W + (((static_cast<int32_t>(right.W) - left.W) * static_cast<int32_t>(progress) + 1) >> 8));
}
RgbwColor RgbwColor::BilinearBlend(const RgbwColor& c00,

View File

@@ -25,8 +25,6 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
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<RgbwColor, int16_t>(*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<RgbwColor, int16_t>(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,6 +230,10 @@ 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
@@ -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)

View File

@@ -24,6 +24,7 @@ License along with NeoPixel. If not, see
<http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------*/
#include <Arduino.h>
#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<uint8_t>(sum / SegmentCount);
return static_cast<uint8_t>(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<int16_t>(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<int32_t>(right.Segment[iSegment]) - left.Segment[iSegment]) * static_cast<int32_t>(progress) + 1) >> 8);
}
return result;
}

View File

@@ -25,8 +25,6 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/
#pragma once
#include <Arduino.h>
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;