Lumiverse
2.5
A framework for creating lighting control applications
|
This class describes a color. More...
#include <LumiverseColor.h>
Public Member Functions | |
LumiverseColor (ColorMode mode=ADDITIVE) | |
Constructs a color. Default color is Black. More... | |
LumiverseColor (map< string, Eigen::Vector3d > basis, ColorMode mode=ADDITIVE) | |
Constructs a color using the provided basis colors. More... | |
LumiverseColor (unordered_map< string, double > params, map< string, Eigen::Vector3d > basis, ColorMode mode, double weight) | |
Constructor for loading from JSON data. | |
LumiverseColor (LumiverseType *other) | |
Copy constructor (from generic LumiverseType) | |
LumiverseColor (LumiverseColor *other) | |
Copy constructor (from pointer) | |
LumiverseColor (const LumiverseColor &other) | |
Copy constructor. | |
virtual | ~LumiverseColor () |
Destroys a color. | |
virtual string | getTypeName () |
Returns the name of the type. More... | |
virtual void | reset () |
Resets the color to defaults. Default color is Black (0, 0, 0). | |
virtual JSONNode | toJSON (string name) |
Converts a color to a JSON object. | |
virtual string | asString () |
Returns the current color. More... | |
double | getX () |
Gets the X tristimulus value for the color. More... | |
double | getY () |
Gets the Y tristimulus value for the color. More... | |
double | getZ () |
Gets the Z tristimulus value for the color. More... | |
Eigen::Vector3d | getXYZ () |
Returns a vector representing the color in XYZ coordinates. More... | |
double | getx () |
Gets the x value. More... | |
double | gety () |
Gets the y value. More... | |
double | getz () |
Gets the z value. More... | |
void | setRGB (double r, double g, double b, double weight=1.0, RGBColorSpace cs=sRGB) |
Sets the color using RGB values. More... | |
Eigen::Vector3d | getRGB (RGBColorSpace cs=sRGB) |
Gets the RGB color as a vector. More... | |
void | setxy (double x, double y, double weight=1.0) |
Sets the color to match the specified xy coordinate (xyY color space) More... | |
Eigen::Vector3d | getxyY () |
Retrieves the xyY coordinate of the current color. More... | |
Eigen::Vector3d | getLab (ReferenceWhite refWhite) |
Retrieves the Lab coordinates for this color. More... | |
Eigen::Vector3d | getLab (Eigen::Vector3d refWhite) |
Retrieves the Lab coordinates for this color with an arbitrary reference white. More... | |
Eigen::Vector3d | getLCHab (ReferenceWhite refWhite) |
Retrieves the LCH(ab) coordintes for this color. More... | |
Eigen::Vector3d | getLCHab (Eigen::Vector3d refWhite) |
Retrives the LCH(ab) coordinates with an arbitrary reference white. More... | |
Eigen::Vector2d | getupvp () |
Gets the u' and v' components of the color. More... | |
Eigen::Vector2d | getuv () |
Get the (u, v) coordinate of the color based on the 1960 CIE color space. More... | |
Eigen::Vector3d | getHSV (RGBColorSpace cs=sRGB) |
Assuming the color has Red, Green, and Blue color channels, this function computes the HSV of the RGB color. Hue is [0,360), Sat and Val are [0,1]. | |
Eigen::Vector2d | getCCT () |
Gets the CCT and Duv value of the color represented by this object. | |
bool | addColorChannel (string name) |
Adds a color channel to the LumiverseColor. More... | |
bool | deleteColorChannel (string name) |
Deletes a color channel from the LumiverseColor. More... | |
bool | setColorChannel (string name, double val) |
Directly sets the value of a light parameter. More... | |
double | getColorChannel (string name) |
Gets the weighted value for the color channel. More... | |
double & | operator[] (string name) |
Subscript overload for accessing light color parameters. More... | |
void | setWeight (double weight) |
Sets the color weight, or overall brightness. More... | |
bool | setRGBRaw (double r, double g, double b, double weight=1.0) |
Sets the device color parameters to the specified RGB value. This will only work correctly if your device is specified to have RGB parameters. More... | |
bool | setHSV (double H, double S, double V, double weight=1.0) |
Sets the RGB channels of the color using a HSV specified color. If the color does not have just RGB channels this operation will fail and return false. H is expected to be [0, 360), S and V are expected to be [0, 1]. More... | |
unordered_map< string, double > | getColorParams () |
Gets the current values for the color parameters. More... | |
double | getWeight () |
Gets the weight. | |
void | operator= (LumiverseColor &other) |
LumiverseColor & | operator+= (double val) |
Adds a constant to the color. | |
LumiverseColor & | operator-= (double val) |
Subtract a constant from the color. | |
LumiverseColor & | operator*= (double val) |
Multiplay a constant to the color. | |
LumiverseColor & | operator/= (double val) |
Divide the color by a constant. | |
shared_ptr< LumiverseType > | lerp (LumiverseColor *rhs, float t) |
Does a linear interpolation of the two colors. More... | |
bool | isEqual (LumiverseColor &other) |
Compares two colors using the color channel values (device levels) More... | |
int | cmpHue (LumiverseColor &other, ReferenceWhite refWhite=D65) |
Compares two colors based on the LCHab hue value. More... | |
virtual bool | isDefault () |
Returns true if the value is equal to the default value for the type. | |
void | changeMode (ColorMode newMode) |
Changes the mode of this color. More... | |
ColorMode | getMode () |
Gets the mode of the color. | |
void | setBasisVector (string channel, double x, double y, double z) |
Sets the value of a basis vector. More... | |
void | removeBasisVector (string channel) |
Removes a basis vector from the color. More... | |
Eigen::Vector3d | getBasisVector (string channel) |
Returns the basis vector for the given color channel. More... | |
const map< string, Eigen::Vector3d > & | getBasisVectors () |
Returns the map of channel name to basis vector. | |
size_t | numBasisVectors () |
Public Member Functions inherited from Lumiverse::LumiverseType | |
virtual | ~LumiverseType () |
Destroys the object. | |
Private Member Functions | |
void | initMode () |
Intialization steps for each particular mode. | |
double | sumComponent (int i) |
Calculates the value of the specified component at current device channel levels. | |
Eigen::Vector3d | RGBtoXYZ (double r, double g, double b, RGBColorSpace cs) |
Helper for converting RGB to XYZ. | |
void | matchChroma (double x, double y, double weight=1.0) |
Runs a linear optimization to find a combination of the basis vectors that will match the target chroma value. More... | |
void | updateXYZ () |
Updates the XYZ cache. | |
bool | doubleEq (double a, double b) |
Private Attributes | |
double | m_weight |
Parameter that controls the overall values of the device channels. More... | |
ColorMode | m_mode |
Color mode for this color. | |
mutex | m_mapMutex |
Protects access to the deviceChannels map. | |
unordered_map< string, double > | m_deviceChannels |
Contains a map from device channel to current value. More... | |
map< string, Eigen::Vector3d > | m_basisVectors |
Basis vectors for each LED source in the light. Represented in XYZ. | |
bool | m_XYZupdated |
Is true if the XYZ cache has been updated. | |
Eigen::Vector3d | m_XYZ |
Cached XYZ value to avoid recomputation if color has not changed. | |
This class describes a color.
LumiverseColor objects are based off of the available color channels that are controllable on the device. If you know the XYZ tristimulus values for each channel, this class will offer a number of functions for converting between XYZ, xyY, RGB, and other color spaces.
Not knowing the XYZ values for a fixture won't prevent you from using the device, but some of the color picking functions won't be available.
Color mixing for LED devices is done by providing the coordinates of the LEDs used in the lights and then taking a linear combination of those basis vectors to match a user-specified target color.
When intializing BASIC* type Colors, you'll find that it's easier to create them programmatically instead of defining them in a Rig file.
Constructs a color. Default color is Black.
Passing in different modes will initialize the light with different settings. BASIC_RGB will base the color around RGB instead of XYZ, while BASIC_CMY will base the color around a CMY color system. SUBTRACTIVE mode is not fully supported yet.
Lumiverse::LumiverseColor::LumiverseColor | ( | map< string, Eigen::Vector3d > | basis, |
ColorMode | mode = ADDITIVE |
||
) |
Constructs a color using the provided basis colors.
basis | Map of axis name to basis vector. These vectors are the colors produced by each individual LED color in the light. If you don't have this information available, the color class will still work but functionality will be limited. |
bool Lumiverse::LumiverseColor::addColorChannel | ( | string | name | ) |
Adds a color channel to the LumiverseColor.
|
virtual |
Returns the current color.
Returns the color in both XYZ and sRGB format, since I'm guessing most people won't know what color some XYZ coordinate represents.
Implements Lumiverse::LumiverseType.
void Lumiverse::LumiverseColor::changeMode | ( | ColorMode | newMode | ) |
Changes the mode of this color.
When changing from Additive or subtractive to a Basic mode, all existing data gets deleted. Use with care.
int Lumiverse::LumiverseColor::cmpHue | ( | LumiverseColor & | other, |
ReferenceWhite | refWhite = D65 |
||
) |
Compares two colors based on the LCHab hue value.
Uses H(ab) to compare colors. H(ab) ranges from 0-360, and arranges colors in chromatic order (red -> violet)
refWhite | Reference white. Defaults to D65. |
bool Lumiverse::LumiverseColor::deleteColorChannel | ( | string | name | ) |
Deletes a color channel from the LumiverseColor.
Eigen::Vector3d Lumiverse::LumiverseColor::getBasisVector | ( | string | channel | ) |
Returns the basis vector for the given color channel.
If it does not exist, a zero vector will be returned.
|
inline |
Gets the weighted value for the color channel.
You should use this function when retrieving data to send over the network.
|
inline |
Gets the current values for the color parameters.
Eigen::Vector3d Lumiverse::LumiverseColor::getLab | ( | ReferenceWhite | refWhite | ) |
Retrieves the Lab coordinates for this color.
Eigen::Vector3d Lumiverse::LumiverseColor::getLab | ( | Eigen::Vector3d | refWhite | ) |
Retrieves the Lab coordinates for this color with an arbitrary reference white.
See http://en.wikipedia.org/wiki/Lab_color_space
Eigen::Vector3d Lumiverse::LumiverseColor::getLCHab | ( | ReferenceWhite | refWhite | ) |
Retrieves the LCH(ab) coordintes for this color.
See http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
Eigen::Vector3d Lumiverse::LumiverseColor::getLCHab | ( | Eigen::Vector3d | refWhite | ) |
Retrives the LCH(ab) coordinates with an arbitrary reference white.
See http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
Eigen::Vector3d Lumiverse::LumiverseColor::getRGB | ( | RGBColorSpace | cs = sRGB | ) |
Gets the RGB color as a vector.
Defaults to useing sRGB as the RGB color space.
cs | Color space to use for the conversion |
|
inlinevirtual |
Eigen::Vector2d Lumiverse::LumiverseColor::getupvp | ( | ) |
Gets the u' and v' components of the color.
These are used in the L*u*v* color space computation but are also a way to measure differences in chroma.
Eigen::Vector2d Lumiverse::LumiverseColor::getuv | ( | ) |
Get the (u, v) coordinate of the color based on the 1960 CIE color space.
This is mainly used for calculating CCT as the 1960 UCS is now obsolete (superseded by CIE 1976, Luv)
double Lumiverse::LumiverseColor::getX | ( | ) |
Gets the X tristimulus value for the color.
If this color is in BASIC_RGB mode, this value will be calculated from the current RGB channel values using the sRGB color space. If you have no basis vectors defined in ADDITIVE mode, -1 will be returned.
double Lumiverse::LumiverseColor::getx | ( | ) |
Gets the x value.
Capitalization is important here. This is x from the CIE chromaticity diagram.
Eigen::Vector3d Lumiverse::LumiverseColor::getxyY | ( | ) |
Retrieves the xyY coordinate of the current color.
|
inline |
Returns a vector representing the color in XYZ coordinates.
If there is no color basis defined, the returned vector will be (-1, -1, -1).
double Lumiverse::LumiverseColor::getY | ( | ) |
Gets the Y tristimulus value for the color.
If this color is in BASIC_RGB mode, this value will be calculated from the current RGB channel values using the sRGB color space. If you have no basis vectors defined in ADDITIVE mode, -1 will be returned.
double Lumiverse::LumiverseColor::gety | ( | ) |
Gets the y value.
Capitalization is important here. This is y from the CIE chromaticity diagram.
double Lumiverse::LumiverseColor::getZ | ( | ) |
Gets the Z tristimulus value for the color.
If this color is in BASIC_RGB mode, this value will be calculated from the current RGB channel values using the sRGB color space. If you have no basis vectors defined in ADDITIVE mode, -1 will be returned.
double Lumiverse::LumiverseColor::getz | ( | ) |
Gets the z value.
Capitalization is important here. This is z from the CIE chromaticity diagram.
bool Lumiverse::LumiverseColor::isEqual | ( | LumiverseColor & | other | ) |
Compares two colors using the color channel values (device levels)
Note that this definitely doesn't guarantee that the chroma values are the same, just that the devices have the same value. You will need to use a different equality function for chroma equality.
shared_ptr< LumiverseType > Lumiverse::LumiverseColor::lerp | ( | LumiverseColor * | rhs, |
float | t | ||
) |
Does a linear interpolation of the two colors.
The object this function is called on is treated as the left hand side. If the colors don't have the same channels (I don't know what you're doing then...) the channels for the left hand side (object this is called on) will be used.
rhs | Initial value |
t | Value between 0 and 1. When t = 0 , this function returns the value of this object. When t = 1 , this function returns the value of rhs. |
|
private |
Runs a linear optimization to find a combination of the basis vectors that will match the target chroma value.
This function prioritizes maintaining the target chromaticity when selecting weights for the basis vectors. It runs a linear solver (CLP Simplex) over a relatively small space. The weights are constrained between 0 and 1, the x and y coordinates calculated from the weights must be equal to the target x and y, and the solver attempts to maximize the sum of the weights.
x | Target x coordinate to match (xyY color space) |
y | Target y coordinate to match (xyY color space) |
weight | Controls the overall brightness of the resulting color. |
double & Lumiverse::LumiverseColor::operator[] | ( | string | name | ) |
Subscript overload for accessing light color parameters.
Note that this function returns the unweighted value for a channel. Be careful when using it to send data over the network.
void Lumiverse::LumiverseColor::removeBasisVector | ( | string | channel | ) |
Removes a basis vector from the color.
Note that if the set of basis vectors does not match the set of color channels, some color calculations will not work correctly.
void Lumiverse::LumiverseColor::setBasisVector | ( | string | channel, |
double | x, | ||
double | y, | ||
double | z | ||
) |
Sets the value of a basis vector.
If a vector does not already exists, this will create a basis vector.
bool Lumiverse::LumiverseColor::setColorChannel | ( | string | name, |
double | val | ||
) |
Directly sets the value of a light parameter.
Available parameters are defined by the user, though common ones will include "Red", "Green", "Blue", "Cyan", etc. This function updates m_deviceChannels and the value will be directly sent to the device.
name | Parameter name (typically the name of a color axis, "Red", "Blue", etc.) |
val | Value to set the parameter to. Clamped between 0 and 1. |
bool Lumiverse::LumiverseColor::setHSV | ( | double | H, |
double | S, | ||
double | V, | ||
double | weight = 1.0 |
||
) |
Sets the RGB channels of the color using a HSV specified color. If the color does not have just RGB channels this operation will fail and return false. H is expected to be [0, 360), S and V are expected to be [0, 1].
void Lumiverse::LumiverseColor::setRGB | ( | double | r, |
double | g, | ||
double | b, | ||
double | weight = 1.0 , |
||
RGBColorSpace | cs = sRGB |
||
) |
Sets the color using RGB values.
Sets the color using normal RGB values like we're all familiar with. If using BASIC_RGB, this function will act exactly like setRGBRaw.
r | Red (0.0 - 1.0) |
g | Green (0.0 - 1.0) |
b | Blue (0.0 - 1.0) |
cs | Color Space to use for converting RGB to XYZ. |
bool Lumiverse::LumiverseColor::setRGBRaw | ( | double | r, |
double | g, | ||
double | b, | ||
double | weight = 1.0 |
||
) |
Sets the device color parameters to the specified RGB value. This will only work correctly if your device is specified to have RGB parameters.
For this to work, you must define m_deviceChannels to include only "Red", "Green" and "Blue". If you construct a color in the SIMPLE_RGB mode, this will be handled for you. Works like a more conventional RGB set method.
void Lumiverse::LumiverseColor::setWeight | ( | double | weight | ) |
Sets the color weight, or overall brightness.
Can be thought of as the "intensity" of the color. Used to make quick color adjustments without modifying the chroma too much.
weight | Weight between 0 and 1 for the color. Values outside the valid range will be clamped to that range. |
void Lumiverse::LumiverseColor::setxy | ( | double | x, |
double | y, | ||
double | weight = 1.0 |
||
) |
Sets the color to match the specified xy coordinate (xyY color space)
Y is excluded since most lights won't be able to match an arbitrary Y coordinate and it's rather dificult to guess at the correct value. We don't like guessing, so use the weight parameter to tune the brightness of a color.
|
private |
Contains a map from device channel to current value.
These are the actual values that get sent to the light after converting from XYZ. Any time you change a value, this map gets recalculated. The map is automatically populated based on the specified basis vectors.
|
private |
Parameter that controls the overall values of the device channels.
Used to make dimmer versions of the same color. Only modifies the deviceChannels map, not the XYZ values directly.