views:

350

answers:

4

Maybe I've had too much coffee, maybe I've been working too long, regardless, I'm at a loss as to what this method does, or rather, why and how it does it, could anyone shed some light upon me? What is the nextColor?

public Color nextColor() {
   int max = 0, min = 1000000000, cr = 0, cg = 0, cb = 0;
   for (int r = 0; r < 256; r += 4) {
      for (int g = 0; g < 256; g += 4) {
         for (int b = 0; b < 256; b += 4) {
            if (r + g + b < 256 || r + g + b > 512) {
               continue;
            }
            min = 1000000000;
            for (Color c : colorTable) {
               int dred   = r - c.getRed();
               int dgreen = g - c.getGreen();
               int dblue  = b - c.getBlue();
               int dif = dred * dred + dgreen * dgreen + dblue * dblue;
               if (min > dif) {
                  min = dif;
               }
            }
            if (max < min) {
               max = min;
               cr  = r;
               cg  = g;
               cb  = b;
            }
         }
      }
   }

   return new Color(cr, cg, cb, 0x90);
}


UPDATE

Thanks for the responses everyone. Looking at the context of the method within the program it is clear that their intent was indeed to return a new Color that is "furthest away" from the set of existing Colors.

Thanks Spar for posing the followup to this question, I will definitely rewrite the above with your advice in mind.

I am not very well versed in the RGB color scale. Knowing the intention of the above method is to retrieve a "complimentary?" color to the existing set of colors, will the solution provided in [1] actually be complimentary in the sense of how we perceive the color? Is there a simpler way to choose a color that will compliment the set, or does the numerical analysis of the RGB components actually yield the appropriate color?

+3  A: 

It seems like you have colortable which is a storing a list of colors.

Then you have this strangely hardcoded colorspace of

Colors that have component which are a multiple of 4 and are "not too bright" but not "too dark either".

This function seems to be giving you the color in the latter which "contrasts" the best with your color table.

When I say contrast , this is defined by choosing the color that is as far as possible from the color table using the 2-norm.

poulejapon
Yes, there's definitely a computation of a "distance" in the color space, but I'm not sure it's giving you the closest...
erickson
yeah sorry it's quite the opposite. It first computes the distance to the set, which is the max of the distance to each element,then it's giving back the color with the smallest distance.
poulejapon
+1  A: 

Given a global array of Color objects named colorTable, this function will find the color from the following colorspace that is the closest* to each one in that array, and then the one of those colors that was farthest away:

Red, Green, Blue components a multiple of 4 Red+Green+Blue between 256 and 512

*:"closest" is defined as the lowest sum of squares of difference for each color component.

As Paul determined, this seems like a plausible, if insanely inefficiently implemented, naive approach to finding a single color that provides a high contrast with the contents of colorTable. The same result could be found with a single pass through colorTable and a bit more math, instead of some 5 million passes through colorTable, and there are much better ways to find a different color that provides a much higher average contrast.

Sparr
A: 

It's trying to get you another color for

a) false-color coding a data set.

b) drawing another line on the graph.

Tim Williscroft
A: 

Consider the case where the pseudo-solid defined by the points in the colorTable has a large "hollow" in its interior, such that nextColor selects the point in the center of that hollow as the nextColor. Depending on what you know about the colorTable, this case could be exceedingly rare. If it is predicted to be rare enough, and you are willing to accept a less than optimal (assuming we take nextColor's output to be optimal) solution in those cases, then a significant optimization presents itself.

In all cases except the above-described one, the color selected by nextColor will be somewhere on the surface of the minimal convex hull enclosing all of the points in the 1/64-dense colorspace defined by your loops. Generating the list of points on that surface is slightly more computationally complex than the simple loops that generate the list of all the points, but it would reduce your search space by about a factor of 25.

In the vast majority of cases, the result of that simplified search will be a point on one of the corners of that convex hull. Considering only those reduces your search space to a trivial list (24 candidates, if my mental geometry serves me well) that could simply be stored ahead of time.

If the nextColor selected from those is "too close" to your colorTable, then you could fall back on running the original type of search in hopes of finding the sort of "hollow" mentioned above. The density of that search could be adapted based on how close the first pass got, and narrowed down from there. That is, if the super fast search finds a nextColor 8 units away from its nearest neighbor in colorTable, then to do better than that you would have to find a hollow at least 16 units across within the colorTable. Run the original search with a step of 8 and store any candidates more than 4 units distant (the hollow is not likely to be aligned with your search grid), then center a radius-12 search of higher density on each of those candidates.

It occurs to me that the 1/64-dense nature (all the multiples of 4) of your search space was probably instituted by the original author for the purpose of speeding up the search in the first place. Given these improvements, you do away with that compromise.

All of this presumes that you want to stick with improvements on this naive method of finding a contrasting color. There are certainly better ways, given equal or more (which colors in colorTable are the most prevalent in your usage? what colors appear more contrast-y to the human eye?) information.

Sparr