Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement ColorHSV #15

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions Adafruit_NeoMatrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,64 @@ uint16_t Adafruit_NeoMatrix::Color(uint8_t r, uint8_t g, uint8_t b) {
(b >> 3);
}

uint16_t Adafruit_NeoMatrix::ColorHSV(uint16_t hue, uint8_t sat, uint8_t val) {

uint8_t r, g, b, r2, g2, b2;

// Remap 0-65535 to 0-1529. Pure red is CENTERED on the 64K rollover;
// 0 is not the start of pure red, but the midpoint...a few values above
// zero and a few below 65536 all yield pure red (similarly, 32768 is the
// midpoint, not start, of pure cyan). The 8-bit RGB hexcone (256 values
// each for red, green, blue) really only allows for 1530 distinct hues
// (not 1536, more on that below), but the full unsigned 16-bit type was
// chosen for hue so that one's code can easily handle a contiguous color
// wheel by allowing hue to roll over in either direction.
hue = (hue * 1530L + 32768) / 65536;

// Convert hue to R,G,B (nested ifs faster than divide+mod+switch):
if(hue < 510) { // Red to Green-1
b = 0;
if(hue < 255) { // Red to Yellow-1
r = 255;
g = hue; // g = 0 to 254
} else { // Yellow to Green-1
r = 510 - hue; // r = 255 to 1
g = 255;
}
} else if(hue < 1020) { // Green to Blue-1
r = 0;
if(hue < 765) { // Green to Cyan-1
g = 255;
b = hue - 510; // b = 0 to 254
} else { // Cyan to Blue-1
g = 1020 - hue; // g = 255 to 1
b = 255;
}
} else if(hue < 1530) { // Blue to Red-1
g = 0;
if(hue < 1275) { // Blue to Magenta-1
r = hue - 1020; // r = 0 to 254
b = 255;
} else { // Magenta to Red-1
r = 255;
b = 1530 - hue; // b = 255 to 1
}
} else { // Last 0.5 Red (quicker than % operator)
r = 255;
g = b = 0;
}

// Apply saturation and value to R,G,B
uint32_t v1 = 1 + val; // 1 to 256; allows >>8 instead of /255
uint16_t s1 = 1 + sat; // 1 to 256; same reason
uint8_t s2 = 255 - sat; // 255 to 0

r2 = ((((r * s1) >> 8) + s2) * v1) >> 8;
g2 = ((((g * s1) >> 8) + s2) * v1) >> 8;
b2 = ((((b * s1) >> 8) + s2) * v1) >> 8;
return Color(r2, g2, b2);
}

// Pass-through is a kludge that lets you override the current drawing
// color with a 'raw' RGB (or RGBW) value that's issued directly to
// pixel(s), side-stepping the 16-bit color limitation of Adafruit_GFX.
Expand Down
2 changes: 2 additions & 0 deletions Adafruit_NeoMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ class Adafruit_NeoMatrix : public Adafruit_GFX, public Adafruit_NeoPixel {

static uint16_t
Color(uint8_t r, uint8_t g, uint8_t b);
static uint16_t
ColorHSV(uint16_t hue, uint8_t sat=255, uint8_t val=255);

private:

Expand Down