- Home /
See if a Color is Within a Threshold
I'm looking for a fast/easy way to simply compare two Color or Color32 objects to apply a threshold to one of my scripts. The script just needs to see if a color is within the range of two colors given by a field. I couldn't find any method provided by the Unity API, and I was wondering if anyone on here might have a good solution. Thanks for any help!
Would it be feasible to convert the colour to HSV , then check if the H value is within the specified ranges ranges (0-360)?
HSV <-> RGB conversion : http://www.cs.rit.edu/~ncs/color/t_convert.html
I have converted the above to uJS, the script can be found at the bottom of this post (ColourCalculator.js) : http://forum.unity3d.com/threads/190968-$$anonymous$$aking-a-Colour-Picker
Unfortunately, I don't really think that'd work for my particular case. Thanks for the thought though. I was just looking for a way to do something like a fuzzy compare. The threshold isn't likely to be very big--just a few increments down/up in the RGB values.
Not completely sure what you are looking for since in one place you say, "simply compare two Color or Color32 objects," and in another say, "within the range of two colors". If you want to see how close two color are to each other, then treat them like a vector and take a look at the magnitude of the difference:
Given:
Color32 col1;
Color32 col2;
Test difference:
Vector3 test1 = new Vector3(col1.r, col1.g, col1.b);
Vector3 test2 = new Vector3(col2.r, col2.b, col2.g);
Debug.Log ((test2 - test1).magnitude);
Set a threshold for magnitude for an acceptable color. You can make it slightly more efficient by using sqr$$anonymous$$agnitude. The code for Color (vs Color32) is a bit simpler since you can subtract variables of type Color.
Sorry I wasn't very clear. I basically want to see if a color is within a range of two colors. Given colorA and colorB, if colorC is in between these two in terms of value (RGB) then I'd like to know.
robertbu, thanks, this helps with my current project.
Answer by DESTRUKTORR · Aug 29, 2013 at 10:58 PM
bool isRedGood = checkedColor.r >= Mathf.Min(color1.r, color2.r) && checkedColor.r <= Mathf.Max(color1.r, color2.r);
bool isGreenGood = checkedColor.g >= Mathf.Min(color1.g, color2.g) && checkedColor.g <= Mathf.Max(color1.g, color2.g);
bool isBlueGood = checkedColor.b >= Mathf.Min(color1.b, color2.b) && checkedColor.b <= Mathf.Max(color1.b, color2.b);
bool isAlphaGood = checkedColor.a >= Mathf.Min(color1.a, color2.a) && checkedColor.a <= Mathf.Max(color1.a, color2.a);// May not need this one if you don't have an alpha channel :P
return isRedGood && isGreenGood && isBlueGood && isAlphaGood;
Assuming you don't know at run-time which color has the max and min for any of the color channels. However, if you do know that, then it's even easier:
bool isRedGood = checkedColor.r >= min.r && checkedColor.r <= max.r;
bool isGreenGood = checkedColor.g >= min.g && checkedColor.g <= max.g;
bool isBlueGood = checkedColor.b >= min.b && checkedColor.b <= max.b;
bool isAlphaGood = checkedColor.a >= min.a && checkedColor.a <= max.a;
return isRedGood && isGreenGood && isBlueGood && isAlphaGood;
It wasn't very pretty, but it's what I was planning on doing anyway. I'll just be sure to make a nice static method. ;)
You might be able to do something a little cleaner using InverseLerp, which will give you a value greater than 0 and less than 1 if a value is strictly between (and not equal to) the border values.
The issue there, Hoeloe, is that you'd still have to run two conditional statements for each color, in addition to doing the inverse lerp, to ensure that each color value is between 0 and 1 XD You'd just be wasting processor time, and making the code less readable by using a more complex, and ultimately unnecessary route.
I only mentioned it as a possibility, I haven't actually thought through how I'd do it. It's probably more sensible to use the individual comparisons anyway, though, as these are likely faster than the InverseLerp call anyway.
That's fairly questionable, but the issue is that the inverselerp call returns a number that must then be checked, anyway, which means that all you've done by calling an inverselerp is change the parameter that you're running the same number of checks on from a float that directly represents the color to a float that represents the linear interpolation parameter of that float given two other floats. It still needs to be checked to see if it is between two values, lol.
Your answer

Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Change the color of the string 2 Answers