color4d: fix incorrect conversion from rgb to HSV when r = g = b.

This commit is contained in:
jean-pierre charras 2017-07-16 17:10:24 +02:00
parent d3b382c281
commit 16cb6a6ca0
2 changed files with 55 additions and 37 deletions

View File

@ -1,10 +1,9 @@
/* /*
* This program source code file is part of KICAD, a free EDA CAD application. * This program source code file is part of KICAD, a free EDA CAD application.
* *
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de * Copyright 2012 Torsten Hueter, torstenhtr <at> gmx.de
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors. * Copyright 2017 Kicad Developers, see AUTHORS.txt for contributors.
* *
* Color class
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -264,7 +263,7 @@ std::ostream &operator<<( std::ostream &aStream, COLOR4D const &aColor )
} }
void COLOR4D::ToHSV( double& aOutH, double& aOutS, double& aOutV ) const void COLOR4D::ToHSV( double& aOutHue, double& aOutSaturation, double& aOutValue ) const
{ {
double min, max, delta; double min, max, delta;
@ -274,41 +273,50 @@ void COLOR4D::ToHSV( double& aOutH, double& aOutS, double& aOutV ) const
max = r > g ? r : g; max = r > g ? r : g;
max = max > b ? max : b; max = max > b ? max : b;
aOutV = max; // v aOutValue = max; // value
delta = max - min; delta = max - min;
if( max > 0.0 ) if( max > 0.0 )
{ {
aOutS = ( delta / max ); // s aOutSaturation = ( delta / max );
} }
else else // for black color (r = g = b = 0 ) saturation is set to 0.
{ {
// r = g = b = 0 // s = 0, v is undefined aOutSaturation = 0.0;
aOutS = 0.0; aOutHue = 0.0;
aOutH = NAN; // its now undefined
return; return;
} }
if( r >= max ) // > is bogus, just keeps compiler happy /* Hue in degrees (0...360) is coded according to this table
aOutH = ( g - b ) / delta; // between yellow & magenta * 0 or 360 : red
else if( g >= max ) * 60 : yellow
aOutH = 2.0 + ( b - r ) / delta; // between cyan & yellow * 120 : green
else * 180 : cyan
aOutH = 4.0 + ( r - g ) / delta; // between magenta & cyan * 240 : blue
* 300 : magenta
*/
if( delta != 0.0 )
{
if( r >= max )
aOutHue = ( g - b ) / delta; // between yellow & magenta
else if( g >= max )
aOutHue = 2.0 + ( b - r ) / delta; // between cyan & yellow
else
aOutHue = 4.0 + ( r - g ) / delta; // between magenta & cyan
aOutH *= 60.0; // degrees aOutHue *= 60.0; // degrees
if( aOutH < 0.0 ) if( aOutHue < 0.0 )
aOutH += 360.0; aOutHue += 360.0;
}
else // delta = 0 means r = g = b. hue is set to 0.0
aOutHue = 0.0;
} }
void COLOR4D::FromHSV( double aInH, double aInS, double aInV ) void COLOR4D::FromHSV( double aInH, double aInS, double aInV )
{ {
double hh, p, q, t, ff; if( aInS <= 0.0 )
long i;
if( aInS <= 0.0 ) // < is bogus, just shuts up warnings
{ {
r = aInV; r = aInV;
g = aInV; g = aInV;
@ -316,19 +324,27 @@ void COLOR4D::FromHSV( double aInH, double aInS, double aInV )
return; return;
} }
hh = aInH; double hh = aInH;
if( hh >= 360.0 ) while( hh >= 360.0 )
hh = 0.0; hh -= 360.0;
/* Hue in degrees (0...360) is coded according to this table
* 0 or 360 : red
* 60 : yellow
* 120 : green
* 180 : cyan
* 240 : blue
* 300 : magenta
*/
hh /= 60.0; hh /= 60.0;
i = (long) hh; int i = (int) hh;
ff = hh - i; double ff = hh - i;
p = aInV * ( 1.0 - aInS ); double p = aInV * ( 1.0 - aInS );
q = aInV * ( 1.0 - ( aInS * ff ) ); double q = aInV * ( 1.0 - ( aInS * ff ) );
t = aInV * ( 1.0 - ( aInS * ( 1.0 - ff ) ) ); double t = aInV * ( 1.0 - ( aInS * ( 1.0 - ff ) ) );
switch( i ) switch( i )
{ {

View File

@ -2,7 +2,7 @@
* This program source code file is part of KICAD, a free EDA CAD application. * This program source code file is part of KICAD, a free EDA CAD application.
* *
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de * Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors. * Copyright (C) 2017 Kicad Developers, see AUTHORS.txt for contributors.
* *
* Color class * Color class
* *
@ -261,17 +261,19 @@ public:
* Function ToHSV() * Function ToHSV()
* Converts current color (stored in RGB) to HSV format. * Converts current color (stored in RGB) to HSV format.
* *
* @param aOutH is conversion result for hue component. * @param aOutHue is the conversion result for hue component, in degrees 0 ... 360.0
* @param aOutS is conversion result for saturation component. * @param aOutSaturation is the conversion result for saturation component (0 ... 1.0).
* @param aOutV is conversion result for value component. * @param aOutValue is conversion result for value component (0 ... 1.0).
* @note saturation is set to 0.0 for black color (r = v = b = 0), and
* hue is set to 0.0 if r = v = b = 0.
*/ */
void ToHSV( double& aOutH, double& aOutS, double& aOutV ) const; void ToHSV( double& aOutHue, double& aOutSaturation, double& aOutValue ) const;
/** /**
* Function FromHSV() * Function FromHSV()
* Changes currently used color to the one given by hue, saturation and value parameters. * Changes currently used color to the one given by hue, saturation and value parameters.
* *
* @param aInH is hue component. * @param aInH is hue component, in degrees.
* @param aInS is saturation component. * @param aInS is saturation component.
* @param aInV is value component. * @param aInV is value component.
*/ */