mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
208 lines
4.5 KiB
C++
208 lines
4.5 KiB
C++
//
|
|
// FILE: map2colour.cpp
|
|
// AUTHOR: Rob Tillaart
|
|
// VERSION: 0.1.4
|
|
// PURPOSE: Arduino library for mapping a float to colour spectrum
|
|
// URL: https://github.com/RobTillaart/map2colour
|
|
//
|
|
// HISTORY:
|
|
// 0.1.0 2021-12-04 initial version.
|
|
// 0.1.1 2021-12-05 add user defined colour-map.
|
|
// add unit tests, update readme.md.
|
|
// 0.1.2 2021-12-06 add map2_565(),
|
|
// add + improve examples.
|
|
// fix value > upper bug
|
|
// 0.1.3 2021-12-07 improve performance map2RGB
|
|
// 0.1.4 2021-12-08 add derived class that is fast and uses more MEMORY / RAM
|
|
//
|
|
|
|
|
|
#include "map2colour.h"
|
|
|
|
|
|
map2colour::map2colour()
|
|
{
|
|
}
|
|
|
|
|
|
bool map2colour::begin(float * values, uint32_t * colourMap)
|
|
{
|
|
// split colour map in channels
|
|
if (colourMap != NULL)
|
|
{
|
|
for (int i = 0; i < 7; i++)
|
|
{
|
|
uint32_t val = colourMap[i];
|
|
_Blue[i] = val & 0xFF;
|
|
val >>= 8;
|
|
_Green[i] = val & 0xFF;
|
|
val >>= 8;
|
|
_Red[i] = val & 0xFF;
|
|
}
|
|
}
|
|
_values = values;
|
|
for (int index = 1; index < 7; index++)
|
|
{
|
|
// catch non increasing values.
|
|
float den = _values[index] - _values[index - 1];
|
|
if (den <= 0.0) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
uint32_t map2colour::map2RGB(float value)
|
|
{
|
|
int index = 1;
|
|
// default values + out of lower range
|
|
uint8_t R = _Red[0];
|
|
uint8_t G = _Green[0];
|
|
uint8_t B = _Blue[0];
|
|
|
|
if (_values[0] < value)
|
|
{
|
|
if (value <= _values[6] )
|
|
{
|
|
// search the interval
|
|
while (_values[index] < value) index++;
|
|
|
|
// base value
|
|
R = _Red[index];
|
|
G = _Green[index];
|
|
B = _Blue[index];
|
|
// calculate the interpolation factor
|
|
// OPTIMIZE USE PRECALCULATED DIVIDERS (costs 24 bytes extra RAM).
|
|
float factor = (_values[index] - value) / (_values[index] - _values[index - 1]);
|
|
|
|
// interpolate if delta <> 0
|
|
int delta = _Red[index] - _Red[index - 1];
|
|
if (delta != 0 ) R -= factor * delta;
|
|
|
|
delta = _Green[index] - _Green[index - 1];
|
|
if (delta != 0 ) G -= factor * delta;
|
|
|
|
delta = _Blue[index] - _Blue[index - 1];
|
|
if (delta != 0 ) B -= factor * delta;
|
|
}
|
|
else
|
|
{
|
|
// out of upper range
|
|
R = _Red[6];
|
|
G = _Green[6];
|
|
B = _Blue[6];
|
|
}
|
|
}
|
|
uint32_t colour = R;
|
|
colour <<= 8;
|
|
colour |= G;
|
|
colour <<= 8;
|
|
colour |= B;
|
|
return colour;
|
|
}
|
|
|
|
|
|
uint16_t map2colour::map2_565(float value)
|
|
{
|
|
uint32_t RGB = map2RGB(value);
|
|
uint16_t colour = 0x0000;
|
|
RGB >>= 3;
|
|
colour |= (RGB & 0x001F); // B channel 5 bits
|
|
RGB >>= 2;
|
|
colour |= (RGB & 0x07E0); // G channel 6 bits
|
|
RGB >>= 3;
|
|
colour |= (RGB & 0xF800); // R channel 5 bits
|
|
return colour;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DERIVED CLASS
|
|
//
|
|
|
|
map2colourFast::map2colourFast() : map2colour()
|
|
{
|
|
}
|
|
|
|
|
|
bool map2colourFast::begin(float * values, uint32_t * colourMap)
|
|
{
|
|
if (map2colour::begin(values, colourMap) == false)
|
|
{
|
|
return false; // non increasing values.
|
|
}
|
|
// calculate dividers
|
|
for (int index = 1; index < 7; index++)
|
|
{
|
|
divFactor[index - 1] = 1.0 / (_values[index] - _values[index - 1]);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
uint32_t map2colourFast::map2RGB(float value)
|
|
{
|
|
int index = 1;
|
|
// default values + out of lower range
|
|
uint8_t R = _Red[0];
|
|
uint8_t G = _Green[0];
|
|
uint8_t B = _Blue[0];
|
|
|
|
if (_values[0] < value)
|
|
{
|
|
if (value <= _values[6] )
|
|
{
|
|
// search the interval
|
|
while (_values[index] < value) index++;
|
|
|
|
// base value
|
|
R = _Red[index];
|
|
G = _Green[index];
|
|
B = _Blue[index];
|
|
// calculate the interpolation factor
|
|
float factor = (_values[index] - value) * divFactor[index - 1];
|
|
|
|
// interpolate if delta <> 0
|
|
int delta = _Red[index] - _Red[index - 1];
|
|
if (delta != 0 ) R -= factor * delta;
|
|
|
|
delta = _Green[index] - _Green[index - 1];
|
|
if (delta != 0 ) G -= factor * delta;
|
|
|
|
delta = _Blue[index] - _Blue[index - 1];
|
|
if (delta != 0 ) B -= factor * delta;
|
|
}
|
|
else
|
|
{
|
|
// out of upper range
|
|
R = _Red[6];
|
|
G = _Green[6];
|
|
B = _Blue[6];
|
|
}
|
|
}
|
|
uint32_t colour = R;
|
|
colour <<= 8;
|
|
colour |= G;
|
|
colour <<= 8;
|
|
colour |= B;
|
|
return colour;
|
|
}
|
|
|
|
|
|
uint16_t map2colourFast::map2_565(float value)
|
|
{
|
|
uint32_t RGB = map2RGB(value);
|
|
uint16_t colour = 0x0000;
|
|
RGB >>= 3;
|
|
colour |= (RGB & 0x001F); // B channel 5 bits
|
|
RGB >>= 2;
|
|
colour |= (RGB & 0x07E0); // G channel 6 bits
|
|
RGB >>= 3;
|
|
colour |= (RGB & 0xF800); // R channel 5 bits
|
|
return colour;
|
|
}
|
|
|
|
|
|
// -- END OF FILE --
|
|
|