Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
HSV.cpp
- Committer:
- JackB
- Date:
- 2015-04-28
- Revision:
- 0:e3c23a157dee
- Child:
- 1:a06dfdf279e2
File content as of revision 0:e3c23a157dee:
/* mbed HSV Library
*
* Copyright (c) 2013-2013 JackB, cstyles
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "HSV.h"
HSV::HSV() {
Rgb.Out = 4095.0;
SetRcf(1.0);
SetGcf(1.0);
SetBcf(1.0);
SetWcf(1.0);
SetH(0.0); // Hue
SetS(1.0); // Saturation
SetV(1.0); // Value
SetP(1.0); // Power
SetPower(true);
}
void HSV::SetPower(bool Power)
{
_Power = Power;
}
int HSV::UseWeb(char* String)
{
// #c08040
char Str[3];
Str[2] = '\0';
Str[0] = String[1];
Str[1] = String[2];
int R = (int)strtol(Str, NULL, 16);
Str[0] = String[3];
Str[1] = String[4];
int G = (int)strtol(Str, NULL, 16);
Str[0] = String[5];
Str[1] = String[6];
int B = (int)strtol(Str, NULL, 16);
return (int)(((R & 0xf8) << 8) + ((G & 0xfc) << 3) + ((B & 0xf8) >> 3));
}
int HSV::UseRGB(int R, int G, int B)
{
return (int)(((R & 0xf8) << 8) + ((G & 0xfc) << 3) + ((B & 0xf8) >> 3));
}
int HSV::UseHSV(float H, float S, float V)
{
Hsv.H = H;
Hsv.S = S;
Hsv.V = V;
HSV_to_RGB();
int R = (int) (sqrt(Rgb.R) * (float)255.0);
int G = (int) (sqrt(Rgb.G) * (float)255.0);
int B = (int) (sqrt(Rgb.B) * (float)255.0);
return (int)(((R & 0xf8) << 8) + ((G & 0xfc) << 3) + ((B & 0xf8) >> 3));
}
void HSV::SetRcf(float Rcf)
{
Rgb.Rcf = Rcf;
HSV_to_RGB();
// RGB_to_HSV();
}
void HSV::SetGcf(float Gcf)
{
Rgb.Gcf = Gcf;
HSV_to_RGB();
// RGB_to_HSV();
}
void HSV::SetBcf(float Bcf)
{
Rgb.Bcf = Bcf;
HSV_to_RGB();
// RGB_to_HSV();
}
void HSV::SetWcf(float Wcf)
{
Rgb.Wcf = Wcf;
HSV_to_RGB();
// RGB_to_HSV();
}
void HSV::SetH(float Hue)
{
Hsv.H = Hue;
HSV_to_RGB();
// RGB_to_HSV();
}
void HSV::SetS(float Saturation)
{
Hsv.S = Saturation;
HSV_to_RGB();
// RGB_to_HSV();
}
void HSV::SetV(float Value)
{
Hsv.V = Value * Value;
HSV_to_RGB();
// RGB_to_HSV();
}
void HSV::SetP(float Value)
{
Hsv.P = Value;
HSV_to_RGB();
// RGB_to_HSV();
}
void HSV::SetW(float White)
{
Rgb.W = White;
}
uint16_t HSV::GetRout(void)
{
if (_Power)
return (uint16_t)(Rgb.R * Rgb.Rcf * Rgb.Out);
return 0;
}
uint16_t HSV::GetGout(void)
{
if (_Power)
return (uint16_t)(Rgb.G * Rgb.Gcf * Rgb.Out);
return 0;
}
uint16_t HSV::GetBout(void)
{
if (_Power)
return (uint16_t)(Rgb.B * Rgb.Bcf * Rgb.Out);
return 0;
}
uint16_t HSV::GetWout(void)
{
if (_Power)
return (uint16_t)(Rgb.W * Rgb.Wcf * Rgb.Out);
return 0;
}
float HSV::GetR(void)
{
return Rgb.R;
}
float HSV::GetG(void)
{
return Rgb.G;
}
float HSV::GetB(void)
{
return Rgb.B;
}
float HSV::GetW(void)
{
return Rgb.W;
}
float HSV::GetH(void)
{
return Hsv.H;
}
float HSV::GetS(void)
{
return Hsv.S;
}
float HSV::GetV(void)
{
return Hsv.V;
}
float HSV::GetH2(void)
{
return Hsv2.H;
}
float HSV::GetS2(void)
{
return Hsv2.S;
}
float HSV::GetV2(void)
{
return Hsv2.V;
}
void HSV::HSV_to_RGB(void)
{
// H is given on [0, 6] or UNDEFINED. S and V are given on [0, 1].
// RGB are each returned on [0, 1].
Rgb.W = ((float)1.0 - Hsv.S) * Hsv.V * Hsv.P;
while (Hsv.H < (float)0.0)
Hsv.H += (float)1.0;
while (Hsv.H >= (float)1.0)
Hsv.H -= (float)1.0;
float h_div = (float)1.0 / (float)6.0;
float h = Hsv.H/h_div;
float s = Hsv.S;
float v = Hsv.V * Hsv.P;
float m, n, f;
int i = floor(h);
f = h - (float) i;
if ( !(i&1) )
f = 1 - f; // if i is even
m = v * (1 - s);
n = v * (1 - s * f);
switch (i) {
case 0 : Rgb.R = v; Rgb.G = n; Rgb.B = m; break;
case 1 : Rgb.R = n; Rgb.G = v; Rgb.B = m; break;
case 2 : Rgb.R = m; Rgb.G = v; Rgb.B = n; break;
case 3 : Rgb.R = m; Rgb.G = n; Rgb.B = v; break;
case 4 : Rgb.R = n; Rgb.G = m; Rgb.B = v; break;
case 5 : Rgb.R = v; Rgb.G = m; Rgb.B = n; break;
default : Rgb.R = v; Rgb.G = n; Rgb.B = m; break;
}
}
void HSV::RGB_to_HSV(void)
{
float rgbMin, rgbMax;
rgbMin = Rgb.R < Rgb.G ? (Rgb.R < Rgb.B ? Rgb.R : Rgb.B) : (Rgb.G < Rgb.B ? Rgb.G : Rgb.B);
rgbMax = Rgb.R > Rgb.G ? (Rgb.R > Rgb.B ? Rgb.R : Rgb.B) : (Rgb.G > Rgb.B ? Rgb.G : Rgb.B);
Hsv2.V = rgbMax;
if (Hsv2.V == 0.0)
{
Hsv2.H = 0.0;
Hsv2.S = 0.0;
return;
}
Hsv2.S = (rgbMax - rgbMin) / Hsv2.V;
if (Hsv2.S == 0.0)
{
Hsv2.H = 0.0;
return;
}
if (rgbMax == Rgb.R)
Hsv2.H = 1.0/6.0 * (Rgb.G - Rgb.B) / (rgbMax - rgbMin);
else if (rgbMax == Rgb.G)
Hsv2.H = 1.0/3.0 + 1.0/6.0 * (Rgb.B - Rgb.R) / (rgbMax - rgbMin);
else
Hsv2.H = 2.0/3.0 + 1.0/6.0 * (Rgb.R - Rgb.G) / (rgbMax - rgbMin);
}