/*
* org.openmicroscopy.shoola.util.ui.colour.HSV
*
*------------------------------------------------------------------------------
* Copyright (C) 2006 University of Dundee. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*------------------------------------------------------------------------------
*/
package org.openmicroscopy.shoola.util.ui.colour;
//Java imports
import java.awt.Color;
//Third-party libraries
//Application-internal dependencies
/**
* HSV class for converting between RGB and HSV values. Stores all values as
* HSV float (h,s,v,a).
*
* @author Jean-Marie Burel
* <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author Donald MacDonald
* <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a>
* @version 3.0
* <small>
* (<b>Internal version:</b> $Revision: $ $Date: $)
* </small>
* @since OME2.2
*/
public class HSV
{
/** Hue component of the colour (0..1). */
private float h;
/** Saturation component of the colour (0..1). */
private float s;
/** Value component of the colour (0..1). */
private float v;
/** Alpha component of the colour (0..1). */
private float a;
/**
* Finds the maximum value of a, b or c. Used to calculate Value and
* Saturation.
*
* @param a One of the values to analyze.
* @param b One of the values to analyze.
* @param c One of the values to analyze.
* @return greatest of(a,b,c)
*/
private float findMin(float a, float b, float c)
{
if (a <= b && a <= c) return a;
if (b <= a && b <= c) return b;
return c;
}
/**
* Finds the minimum value of a, b or c. Used to calculate Value and
* Saturation.
*
* @param a One of the values to analyze.
* @param b One of the values to analyze.
* @param c One of the values to analyze.
* @return smallest of(a,b,c)
*/
private float findMax(float a, float b, float c)
{
if (a >= b && a >= c) return a;
if (b >= a && b >= c) return b;
return c;
}
/** Constructor of the HSV component (sets all values to 0). */
public HSV()
{
h = 0;
s = 0;
v = 0;
a = 0;
}
/**
* Constructor of the HSV component (sets all values to the parameter c)
*
* @param c HSV colour to copy.
*/
public HSV(HSV c)
{
h = c.h;
s = c.s;
v = c.v;
a = c.a;
}
/**
* Constructor of the HSV component (sets all values to the parameter c)
*
* @param c RGB colour to copy (uses the {@link #fromColor(Color)} method.
*/
public HSV(Color c)
{
this.fromColor(c);
}
/**
* Constructor of the HSV component. Initialises the values with the
* parameters provided, has an alpha channel.
*
* @param hs hue.
* @param ss saturation.
* @param vs value.
* @param as alpha.
*/
public HSV(float hs, float ss, float vs, float as)
{
h = hs;
s = ss;
v = vs;
a = as;
}
/**
* Constructor of the HSV component. Initialises the values with the
* parameters provided, has no alpha channel.
*
* @param hs hue.
* @param ss saturation.
* @param vs value.
*/
public HSV(float hs, float ss, float vs)
{
h = hs;
s = ss;
v = vs;
a = 1;
}
/**
* Sets the current HSV values from the RGB parameter c.
*
* @param c RGB Colour to set the HSV values from.
*/
public void fromColor(Color c)
{
float min, max, delta;
min = findMin(c.getRed(), c.getGreen(), c.getBlue());
max = findMax(c.getRed(), c.getGreen(), c.getBlue());
v = max;
delta = max-min;
if (max != 0.0f) s = delta/max;
else
{
v = 0.0f;
s = 0.0f;
h = 0.0f;
}
if (c.getRed()==max)
h = (c.getGreen()-c.getBlue())/delta;
else if (c.getGreen() == max)
h = 2.0f + (c.getBlue()-c.getRed())/delta;
else
h = 4.0f+(c.getRed()-c.getGreen())/delta;
h = h * 60.0f;
if (h < 0) h += 360.0f;
h = h/360.0f;
v = v/255.0f;
a = c.getAlpha()/255.0f;
}
/**
* Converts HSV values to RGB Colour components less alpha parameter.
*
* @return See above.
*/
public Color toColor()
{
int i;
float f, p, q, t;
float r, g, b;
float hquad;
if (s == 0) {
r = g = b = v;
return new Color(r, g, b, a);
}
hquad = h*6;
i = (int) Math.floor(hquad);
f = hquad-i;
p = v*(1-s);
q = v*(1-s*f);
t = v*(1-s*(1-f));
switch (i) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default:
r = v;
g = p;
b = q;
break;
}
return new Color(r, g, b, 1);
}
/**
* Converts HSV values to RGB Colour components with alpha channel.
*
* @return See above.
*/
public Color toColorA()
{
int i;
float f, p, q, t;
float r, g, b;
float hquad;
if (s == 0) {
r = g = b = v;
return new Color(r, g, b, a);
}
hquad = h*6;
i = (int) Math.floor(hquad);
f = hquad-i;
p = v*(1-s);
q = v*(1-s*f);
t = v*(1-s*(1-f));
switch (i) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default:
r = v;
g = p;
b = q;
break;
}
return new Color(r, g, b, a);
}
/**
* Returns the hue component of the colour (0..1).
*
* @return See above.
*/
public float getHue() { return h; }
/**
* Returns the saturation component of the colour (0..1).
*
* @return See above.
*/
public float getSaturation() { return s; }
/**
* Returns the value component of the colour (0..1).
*
* @return See above.
*/
public float getValue() { return v; }
/**
* Returns the alpha component of the colour (0..1).
*
* @return See above.
*/
public float getAlpha() { return a; }
/**
* Sets the hue component of the colour (0..1).
*
* @param h The hue.
*/
public void setHue(float h) { this.h = h; }
/**
* Sets the saturation component of the colour (0..1).
*
* @param s The saturation.
*/
public void setSaturation(float s) { this.s = s; }
/**
* Sets the value component of the colour (0..1).
*
* @param v The value.
*/
public void setValue(float v) { this.v = v; }
/**
* Sets the alpha component of the colour (0..1).
*
* @param a The alpha.
*/
public void setAlpha(float a) { this.a = a; }
}