-
Notifications
You must be signed in to change notification settings - Fork 5
colorObj
We're human, we love colors. All sorts of hardware deals with color. Wouldn't it be nice to have a common object that can contain and manipulate colors? Take a color from one piece of hardware and pass it to another? Take a starting point of a color and blend other colors into it to create new colors? This is what colorObj is all about. Describing and manipulating colors to use with different hardware.
colorObj(RGBpack* buff)
If you look at the memory required to hold a color object, it typically runs at about 8 bytes. This is fine until you want a bunch of them, like with a bitmap. Suddenly you really want this information packed as tightly as possible. An RGBpack holds a color packed down to 3 bytes per color (Or pixel). Less than half the memory footprint, with no loss of information. This constructor is for creating a color object from a RGBpack color.
colorObj(byte inRed, byte inGreen, byte inBlue)
Your standard "build a color from primary red green and blue values". The primary values are 0..255 or, one byte each.
//colorObj(colorObj* inColor)
This one I was never able to get to work. Its a copy constructor taking a pointer to a colorObj and using that to create a new instance of itself. The problem was that the compiler kept getting this constructor mixed up with the next constructor that takes a word as input.
colorObj(word color16)
color16 is a special way to describe a color in 16 bits (2 bytes). You do loose some color information with this compression. On the other hand, its used by a large variety of displays. Actually, every one I've used as of this writing. So its very important to have in our bag of tricks. This is why it was kept instead of the copy constructor above.
colorObj(void)
The "I don't care what color, just allocate some room" constructor. Very handy for grabbing a "blank" color to use as a receptacle for building a new color.
// Red,Grn,blu
#define LC_BLACK 0, 0, 0
#define LC_CHARCOAL 50, 50, 50
#define LC_DARK_GREY 140,140,140
#define LC_GREY 185,185,185
#define LC_LIGHT_GREY 250,250,250
#define LC_WHITE 255,255,255
#define LC_RED 255, 0, 0
#define LC_PINK 255,130,208
#define LC_GREEN 0,255, 0
#define LC_DARK_GREEN 0, 30, 0
#define LC_OLIVE 30, 30, 1
#define LC_BLUE 0, 0,255
#define LC_LIGHT_BLUE 164,205,255
#define LC_NAVY 0, 0, 30
#define LC_PURPLE 140, 0,255
#define LC_LAVENDER 218,151,255
#define LC_ORANGE 255,128, 0
#define LC_CYAN 0,255,255
#define LC_MAGENTA 255, 0,255
#define LC_YELLOW 255,255, 0
Yes! I used #define. Hahahaha!!! I use it EVERYWHERE!!!!! They said I was crazy. It's THEM! They're the ones that are crazy!!!!!!!!!
Ah, err... Well, anyway..
These are a set of handy starting points for building colors. They are #define-ed in a way that they plug directly into the standard primary constructor. And into the setColor() method.
For example:
colorObj aColor(LC_LIGHT_BLUE);
And now aColor is holding a light blue color.
There are more? Of course there's more! More useful starting points.
Many of the color methods have pointers to color objects as input parameters. Now, intead of creating new colors every time, there is a prebuilt set that can be used for these kinds of calls.
colorObj red;
colorObj blue;
colorObj white;
colorObj black;
colorObj green;
colorObj cyan;
colorObj magenta;
colorObj yellow;
For example :
aColor.blend(&black,50);
This will blend 50% of the color black into aColor making it, just that much darker.
void setColor(RGBpack* buff);
Sets the current color to the color of the passed in RGBpack color.
void setColor(byte inRed, byte inGreen, byte inBlue);
Sets the current color to the color described by the three primary colors.
void setColor(word color16);
Sets the current color to the color described by the compressed 16bit color. If the 16bit color is a "known" color the decompression will be lossless, otherwise it will do the best job it can matching up a color from the inputted data.
void setColor(colorObj* inColor); // Why doesn't this one get confused? Who knows?
Set the current color to the color that is pointed to by the passed in color object pointer.
word getColor16(void);
Create a compressed 16 bit color from the current color object.
byte getRed(void);
Pass back the 8 bit red component of this color object.
byte getGreen(void);
Pass back the 8 bit green component of this color object.
byte getBlue(void);
Pass back the, wait for it, blue component of this color object. I bet you never saw that coming!
RGBpack packColor(void);
Pack the current color into an RGBpack for tight storage.
colorObj mixColors(colorObj* mixinColor,byte mixPercent);
Creates a new color my mixing the current color with the mix percent of the inputed color.
void blend(colorObj* mixinColor,byte mixPercent);
Blend the mix percent of the inputted color into the current color changing the current color into a new color. This one is probably the most popular call in the entire library. This is also the foundation to color mappers. Color mappers are so insanely handy.. You'll have to sit down and take a few deep breaths, just to get over the amazement!
void printRGB(void);
Sends the information of a color object to the serial monitor. Quite handy, but there's a catch. You'll have to use a #define to use it. Why? Because it only exists if PRINT_COLOR is defined.
But not to worry, its only for debugging so you may not ever need to use it.
Solid colors are fun, but you'd have a rough time trying to show a sunset with them. Well, actually solid colors can be pretty boring. People really like color gradients and that's where the colorMapper class comes in.
Think about a late evening sky where the horizon goes from dark blue to black. A color mapper maps numbers 0..100 to colors color0..color1. The colors can be -any- two color objects. You pop in any number between 0..100 and it'll pop out the corresponding color between color0..color1. Very handy!
colorMapper(void);
The standard "give me a blank color mapper I can use" constructor.
colorMapper(colorObj* inStart, colorObj* inEnd);
The more commonly used color mapper constructor that takes both starting and ending color objects.
colorMapper(word startC16,word endC16);
The seldom used constructor that takes compressed color16 colors as inputs.
void setColors(colorObj* inStart, colorObj* inEnd);
This is for setting or changing the endpoint colors of a color mapper.
colorObj Map(float percent);
This is how we make the mapper do its thing. Pass in a number from 0..100 and it will pass back the corresponding color. And yes, you will need to allocate a space to store this new color.
void printColors(void);
Just like in the colorObj class above, there is a way to send the mapper color information to the serial monitor for debugging. And just like the colorObj above, you will have to #define PRINT_COLOR for this to exist.
The color mapper is a great tool. But, as a stand alone it is limited. The colorMultiMap is a far more useful tool. Think about drawing the scale on a tachometer. Say 0..5,000 RMP is fine (green) 5,000..6,500 is ok (Yellow) over 6,500 is bad! (red) A three color gradient. How would you set this up? Grab a colorMultiMap and add in the thee colors end points 0,green 5000,green 5010,yellow 6490,yellow 6500,red.
colorMultiMap tachMapper;
tachMapper.addColor(0,&green);
tachMapper.addColor(5000,&green);
tachMapper.addColor(5010,&yellow);
tachMapper.addColor(6490,&yellow);
tachMapper.addColor(6500,&red);
Notice there's actually preset starting colors ready for this? Its almost like this is something that has been done before.
Now, to use the mapper? calculate your RPM, and drop it into the mapper to get the corresponding color.
colorObj Map(double inVal);
And really that's how easy it is to use. Also notice that we give a 10 RPM spread between green/yellow and between yellow/red? This will be filled by mapping between the two colors. The resulting color can be used for a color display, RGB LED, Neopixel whatever. All the work has been taken care of for you. Give it your input value, pull out the color and hand it off to your display hardware. Done!
colorMultiMap(void);
There is only this one. colorMultiMap objects are created as blanks. The color information is added in after the fact.
void addColor(double inX, colorObj* color);
Add a color at a numeric point. The number can be anything. Typically you use the units your want to work in. Degrees C, RPM, Moisture.. Whatever you like. The color is what color corresponds to that numeric value. You can add as many value/color pairs as you need, by calling this method repeatedly with each set of values.
void clearMap(void);
Clear a color mapper of all value pairs. Used if you want to completely change a color map for a new set of color information.
colorObj Map(double inVal);
As in the basic color mapper above, it takes a numeric value, and it returns the corresponding color. The big difference here is that the value you input is NOT constrained to 0..100 pecent. It uses the units you choose and can be any value you want.
If you try to map a value that's out of range, its not a big issue. If its larger than the mapping range, the mapper will return the value for the largest range. If its smaller than the smallest range, it'll return the value for the smallest range.